From 404ee3fec442838b068a79df338bb5074947b599 Mon Sep 17 00:00:00 2001 From: emily Date: Mon, 11 May 2026 09:15:08 +0200 Subject: [PATCH] a --- .gitignore | 336 + ATAPAuditor/ATAPAuditor.psd1 | 45 + ATAPAuditor/ATAPAuditor.psm1 | 931 + ...Benchmark-FBPro-1.2.1#RegistrySettings.ps1 | 1852 ++ .../AuditGroups/Debian Linux 11-CIS-1.0.0.ps1 | 5295 +++++ .../AuditGroups/Debian Linux 12-CIS-1.0.1.ps1 | 4115 ++++ ...security settings-FBPro-1.0#UserRights.ps1 | 184 + ...ogle Chrome-CIS-2.0.0#RegistrySettings.ps1 | 2402 ++ ...gle Chrome-DISA-V1R15#RegistrySettings.ps1 | 1296 ++ ...rosoft Edge-CIS-2.0.0#RegistrySettings.ps1 | 4854 ++++ ...ft Edge-Microsoft-117#RegistrySettings.ps1 | 684 + ...Explorer 11-CIS-1.0.0#RegistrySettings.ps1 | 5650 +++++ ...xplorer 11-DISA-V1R16#RegistrySettings.ps1 | 4968 ++++ ...t Explorer 11-MS-2004#RegistrySettings.ps1 | 4860 ++++ ... Enterprise-CIS-1.2.0#RegistrySettings.ps1 | 11884 ++++++++++ ...s 10 GDPR-MS-16082019#RegistrySettings.ps1 | 4215 ++++ ...10 SiSyPHuS HD-BSI-1.3#AccountPolicies.ps1 | 255 + ...s 10 SiSyPHuS HD-BSI-1.3#AuditPolicies.ps1 | 77 + ...0 SiSyPHuS HD-BSI-1.3#RegistrySettings.ps1 | 12419 ++++++++++ ...10 SiSyPHuS HD-BSI-1.3#SecurityOptions.ps1 | 156 + ...dows 10 SiSyPHuS HD-BSI-1.3#UserRights.ps1 | 1479 ++ ...SiSyPHuS Logging-BSI-1.3#AuditPolicies.ps1 | 1502 ++ ...yPHuS Logging-BSI-1.3#RegistrySettings.ps1 | 711 + ...10 SiSyPHuS NE-BSI-1.3#AccountPolicies.ps1 | 171 + ...s 10 SiSyPHuS NE-BSI-1.3#AuditPolicies.ps1 | 77 + ...0 SiSyPHuS NE-BSI-1.3#RegistrySettings.ps1 | 8320 +++++++ ...10 SiSyPHuS NE-BSI-1.3#SecurityOptions.ps1 | 130 + ...dows 10 SiSyPHuS NE-BSI-1.3#UserRights.ps1 | 1385 ++ ...s-Telemetrie-BSI-V1.2#RegistrySettings.ps1 | 289 + ...t Windows 10-ACSC-21H1#AccountPolicies.ps1 | 199 + ...oft Windows 10-ACSC-21H1#AuditPolicies.ps1 | 1217 + ... Windows 10-ACSC-21H1#RegistrySettings.ps1 | 12743 +++++++++++ ...t Windows 10-ACSC-21H1#SecurityOptions.ps1 | 110 + ...rosoft Windows 10-ACSC-21H1#UserRights.ps1 | 926 + ...t Windows 10-CIS-3.0.0#AccountPolicies.ps1 | 283 + ...oft Windows 10-CIS-3.0.0#AuditPolicies.ps1 | 1616 ++ ... Windows 10-CIS-3.0.0#RegistrySettings.ps1 | 17452 ++++++++++++++ ...t Windows 10-CIS-3.0.0#SecurityOptions.ps1 | 130 + ...rosoft Windows 10-CIS-3.0.0#UserRights.ps1 | 1488 ++ ... Windows 10-DISA-V1R23#AccountPolicies.ps1 | 252 + ...ft Windows 10-DISA-V1R23#AuditPolicies.ps1 | 1559 ++ ...Windows 10-DISA-V1R23#RegistrySettings.ps1 | 4142 ++++ ... Windows 10-DISA-V1R23#SecurityOptions.ps1 | 130 + ...osoft Windows 10-DISA-V1R23#UserRights.ps1 | 956 + ...dows 10-Microsoft-21H1#AccountPolicies.ps1 | 196 + ...indows 10-Microsoft-21H1#AuditPolicies.ps1 | 1388 ++ ...ows 10-Microsoft-21H1#RegistrySettings.ps1 | 10968 +++++++++ ...dows 10-Microsoft-21H1#SecurityOptions.ps1 | 26 + ...t Windows 10-Microsoft-21H1#UserRights.ps1 | 882 + ...-Stand-alone-CIS-2.0.0#AccountPolicies.ps1 | 255 + ...10-Stand-alone-CIS-2.0.0#AuditPolicies.ps1 | 1616 ++ ...Stand-alone-CIS-2.0.0#RegistrySettings.ps1 | 16305 +++++++++++++ ...-Stand-alone-CIS-2.0.0#SecurityOptions.ps1 | 130 + ...ws 10-Stand-alone-CIS-2.0.0#UserRights.ps1 | 1312 ++ ...t Windows 11-CIS-4.0.0#AccountPolicies.ps1 | 284 + ...oft Windows 11-CIS-4.0.0#AuditPolicies.ps1 | 1616 ++ ... Windows 11-CIS-4.0.0#RegistrySettings.ps1 | 18823 ++++++++++++++++ ...t Windows 11-CIS-4.0.0#SecurityOptions.ps1 | 130 + ...rosoft Windows 11-CIS-4.0.0#UserRights.ps1 | 1509 ++ ...dows 11-Microsoft-22H2#AccountPolicies.ps1 | 196 + ...indows 11-Microsoft-22H2#AuditPolicies.ps1 | 1388 ++ ...ows 11-Microsoft-22H2#RegistrySettings.ps1 | 12011 ++++++++++ ...dows 11-Microsoft-22H2#SecurityOptions.ps1 | 26 + ...t Windows 11-Microsoft-22H2#UserRights.ps1 | 875 + ...-Stand-alone-CIS-2.0.0#AccountPolicies.ps1 | 255 + ...11-Stand-alone-CIS-2.0.0#AuditPolicies.ps1 | 1616 ++ ...Stand-alone-CIS-2.0.0#RegistrySettings.ps1 | 16049 +++++++++++++ ...-Stand-alone-CIS-2.0.0#SecurityOptions.ps1 | 130 + ...ws 11-Stand-alone-CIS-2.0.0#UserRights.ps1 | 1311 ++ ...ft Windows 7-CIS-3.1.0#AccountPolicies.ps1 | 255 + ...soft Windows 7-CIS-3.1.0#AuditPolicies.ps1 | 1388 ++ ...t Windows 7-CIS-3.1.0#RegistrySettings.ps1 | 10042 +++++++++ ...ngs-FB Pro GmbH-1.2.1#RegistrySettings.ps1 | 144 + ... Settings-FB Pro GmbH-1.2.1#UserRights.ps1 | 102 + ...rver 2012 R2-CIS-3.0.0#AccountPolicies.ps1 | 255 + ...Server 2012 R2-CIS-3.0.0#AuditPolicies.ps1 | 1922 ++ ...ver 2012 R2-CIS-3.0.0#RegistrySettings.ps1 | 12455 ++++++++++ ...rver 2012 R2-CIS-3.0.0#SecurityOptions.ps1 | 133 + ...ws Server 2012 R2-CIS-3.0.0#UserRights.ps1 | 1937 ++ ...ver 2012 R2-DISA-V2R19#AccountPolicies.ps1 | 252 + ...erver 2012 R2-DISA-V2R19#AuditPolicies.ps1 | 1217 + ...er 2012 R2-DISA-V2R19#RegistrySettings.ps1 | 6330 ++++++ ... Server 2016-CIS-3.0.0#AccountPolicies.ps1 | 283 + ...ws Server 2016-CIS-3.0.0#AuditPolicies.ps1 | 2036 ++ ...Server 2016-CIS-3.0.0#RegistrySettings.ps1 | 12380 ++++++++++ ... Server 2016-CIS-3.0.0#SecurityOptions.ps1 | 133 + ...ndows Server 2016-CIS-3.0.0#UserRights.ps1 | 1984 ++ ...ndows Server 2016-DISA-1.12#UserRights.ps1 | 71 + ...Server 2016-DISA-V1R12#AccountPolicies.ps1 | 252 + ...s Server 2016-DISA-V1R12#AuditPolicies.ps1 | 1502 ++ ...erver 2016-DISA-V1R12#RegistrySettings.ps1 | 3437 +++ ...Server 2016-DISA-V1R12#SecurityOptions.ps1 | 104 + ...r 2016-Microsoft-FINAL#AccountPolicies.ps1 | 252 + ...ver 2016-Microsoft-FINAL#AuditPolicies.ps1 | 1274 ++ ... 2016-Microsoft-FINAL#RegistrySettings.ps1 | 3658 +++ ...Server 2016-Microsoft-FINAL#UserRights.ps1 | 1031 + ... Server 2019-CIS-3.0.0#AccountPolicies.ps1 | 283 + ...ws Server 2019-CIS-3.0.0#AuditPolicies.ps1 | 2036 ++ ...Server 2019-CIS-3.0.0#RegistrySettings.ps1 | 12919 +++++++++++ ... Server 2019-CIS-3.0.0#SecurityOptions.ps1 | 133 + ...ndows Server 2019-CIS-3.0.0#UserRights.ps1 | 1979 ++ ... Server 2019-DISA-V1R5#AccountPolicies.ps1 | 252 + ...ws Server 2019-DISA-V1R5#AuditPolicies.ps1 | 1502 ++ ...Server 2019-DISA-V1R5#RegistrySettings.ps1 | 3482 +++ ... Server 2019-DISA-V1R5#SecurityOptions.ps1 | 104 + ...r 2019-Microsoft-FINAL#AccountPolicies.ps1 | 252 + ...ver 2019-Microsoft-FINAL#AuditPolicies.ps1 | 1388 ++ ... 2019-Microsoft-FINAL#RegistrySettings.ps1 | 9235 ++++++++ ...r 2019-Microsoft-FINAL#SecurityOptions.ps1 | 52 + ...Server 2019-Microsoft-FINAL#UserRights.ps1 | 897 + ... Server 2022-CIS-3.0.0#AccountPolicies.ps1 | 283 + ...ws Server 2022-CIS-3.0.0#AuditPolicies.ps1 | 2036 ++ ...Server 2022-CIS-3.0.0#RegistrySettings.ps1 | 13246 +++++++++++ ... Server 2022-CIS-3.0.0#SecurityOptions.ps1 | 133 + ...ndows Server 2022-CIS-3.0.0#UserRights.ps1 | 1985 ++ ... Server 2022-DISA-V1R1#AccountPolicies.ps1 | 252 + ...ws Server 2022-DISA-V1R1#AuditPolicies.ps1 | 1502 ++ ...Server 2022-DISA-V1R1#RegistrySettings.ps1 | 3509 +++ ... Server 2022-DISA-V1R1#SecurityOptions.ps1 | 104 + ...r 2022-Microsoft-FINAL#AccountPolicies.ps1 | 196 + ...ver 2022-Microsoft-FINAL#AuditPolicies.ps1 | 1730 ++ ... 2022-Microsoft-FINAL#RegistrySettings.ps1 | 9699 ++++++++ ...r 2022-Microsoft-FINAL#SecurityOptions.ps1 | 26 + ...Server 2022-Microsoft-FINAL#UserRights.ps1 | 925 + ... Server 2025-CIS-1.0.0#AccountPolicies.ps1 | 257 + ...ws Server 2025-CIS-1.0.0#AuditPolicies.ps1 | 2036 ++ ...Server 2025-CIS-1.0.0#RegistrySettings.ps1 | 14316 ++++++++++++ ... Server 2025-CIS-1.0.0#SecurityOptions.ps1 | 133 + ...ndows Server 2025-CIS-1.0.0#UserRights.ps1 | 1987 ++ ATAPAuditor/AuditGroups/RSSeverityTests.ps1 | 2509 ++ .../Red Hat Enterprise Linux 9-CIS-1.0.0.ps1 | 3832 ++++ .../Red Hat Enterprise Linux 9-CIS-2.0.0.ps1 | 4148 ++++ .../AuditGroups/SBD - Application Control.ps1 | 68 + .../SBD - Connectivity Security.ps1 | 1434 ++ .../AuditGroups/SBD - Linux Base Security.ps1 | 462 + .../AuditGroups/SBD - Platform Security.ps1 | 569 + .../AuditGroups/SBD - PowerShell Security.ps1 | 204 + .../SBD - Windows Base Security.ps1 | 622 + .../SUSE Linux Enterprise 15-CIS-1.1.1.ps1 | 3541 +++ .../Ubuntu Linux 20.04-CIS-1.1.0.ps1 | 5012 ++++ .../Ubuntu Linux 22.04-CIS-2.0.0.ps1 | 4109 ++++ ATAPAuditor/Helpers/AuditGroupFunctions.ps1 | 543 + ATAPAuditor/Helpers/Firewall.ps1 | 83 + ATAPAuditor/Helpers/HashHelper.ps1 | 58 + ATAPAuditor/Helpers/LinuxHelper.ps1 | 106 + ATAPAuditor/Helpers/LogFile.ps1 | 94 + ATAPAuditor/Helpers/Menu.ps1 | 142 + ATAPAuditor/Helpers/ReportUnixOS.ps1 | 20 + ATAPAuditor/Helpers/ReportWindowsOS.ps1 | 41 + ATAPAuditor/Helpers/SecurityPolicy.psm1 | 36 + .../Debian_11/CIS-Debian-1.1.1.1.sh | 32 + .../Debian_11/CIS-Debian-1.1.1.2.sh | 31 + .../Debian_11/CIS-Debian-1.1.1.3.sh | 31 + .../Debian_11/CIS-Debian-1.1.10.sh | 35 + .../Debian_11/CIS-Debian-1.5.1.sh | 18 + .../Debian_11/CIS-Debian-1.8.2.sh | 73 + .../Debian_11/CIS-Debian-1.8.3.sh | 43 + .../Debian_11/CIS-Debian-1.8.4.sh | 70 + .../Debian_11/CIS-Debian-1.8.5.sh | 65 + .../Debian_11/CIS-Debian-1.8.6.sh | 75 + .../Debian_11/CIS-Debian-1.8.7.sh | 65 + .../Debian_11/CIS-Debian-1.8.8.sh | 76 + .../Debian_11/CIS-Debian-1.8.9.sh | 43 + .../Debian_11/CIS-Debian-2.1.1.1.sh | 37 + .../Debian_11/CIS-Debian-3.1.1.sh | 15 + .../Debian_11/CIS-Debian-3.1.2.sh | 29 + .../Debian_11/CIS-Debian-3.1.3.sh | 40 + .../Debian_11/CIS-Debian-3.1.4.sh | 39 + .../Debian_11/CIS-Debian-3.1.5.sh | 42 + .../Debian_11/CIS-Debian-3.1.6.sh | 38 + .../Debian_11/CIS-Debian-3.2.1.sh | 33 + .../Debian_11/CIS-Debian-3.2.2.sh | 54 + .../Debian_11/CIS-Debian-3.3.1.sh | 56 + .../Debian_11/CIS-Debian-3.3.2.sh | 56 + .../Debian_11/CIS-Debian-3.3.3.sh | 35 + .../Debian_11/CIS-Debian-3.3.4.sh | 35 + .../Debian_11/CIS-Debian-3.3.5.sh | 34 + .../Debian_11/CIS-Debian-3.3.6.sh | 34 + .../Debian_11/CIS-Debian-3.3.7.sh | 33 + .../Debian_11/CIS-Debian-3.3.8.sh | 33 + .../Debian_11/CIS-Debian-3.3.9.sh | 56 + .../Debian_11/CIS-Debian-3.5.1.6.sh | 5 + .../Debian_11/CIS-Debian-4.1.3.6-A.sh | 7 + .../Debian_11/CIS-Debian-4.1.3.6-B.sh | 10 + .../Debian_11/CIS-Debian-4.1.5.sh | 2 + .../Debian_11/CIS-Debian-4.2.3.sh | 68 + .../Debian_11/CIS-Debian-5.2.2.sh | 24 + .../Debian_11/CIS-Debian-5.4.5.sh | 12 + .../Debian_11/CIS-Debian-5.5.1.5.sh | 9 + .../Debian_11/CIS-Debian-5.5.2.sh | 4 + .../Debian_11/CIS-Debian-5.5.4.sh | 7 + .../Debian_11/CIS-Debian-5.5.5.sh | 13 + .../Debian_11/CIS-Debian-6.2.11.sh | 13 + .../Debian_11/CIS-Debian-6.2.12.sh | 13 + .../Debian_11/CIS-Debian-6.2.13.sh | 20 + .../Debian_11/CIS-Debian-6.2.14.sh | 29 + .../Debian_11/CIS-Debian-6.2.15.sh | 16 + .../Debian_11/CIS-Debian-6.2.16.sh | 16 + .../Debian_11/CIS-Debian-6.2.17.sh | 20 + .../Debian_11/CIS-Debian-6.2.3.sh | 9 + .../Debian_11/CIS-Debian-6.2.5.sh | 10 + .../Debian_11/CIS-Debian-6.2.6.sh | 4 + .../Debian_11/CIS-Debian-6.2.7.sh | 4 + .../Debian_11/CIS-Debian-6.2.8.sh | 4 + .../Debian_11/CIS-Debian-6.2.9.sh | 9 + .../ShellScripts/RHEL9/CIS100_RHEL9_1111.sh | 33 + .../ShellScripts/RHEL9/CIS100_RHEL9_1112.sh | 32 + .../ShellScripts/RHEL9/CIS100_RHEL9_119.sh | 32 + .../ShellScripts/RHEL9/CIS100_RHEL9_182.sh | 52 + .../ShellScripts/RHEL9/CIS100_RHEL9_183.sh | 41 + .../ShellScripts/RHEL9/CIS100_RHEL9_184.sh | 55 + .../ShellScripts/RHEL9/CIS100_RHEL9_185.sh | 45 + .../ShellScripts/RHEL9/CIS100_RHEL9_186.sh | 61 + .../ShellScripts/RHEL9/CIS100_RHEL9_187.sh | 45 + .../ShellScripts/RHEL9/CIS100_RHEL9_188.sh | 53 + .../ShellScripts/RHEL9/CIS100_RHEL9_189.sh | 36 + .../ShellScripts/RHEL9/CIS100_RHEL9_312.sh | 40 + .../ShellScripts/RHEL9/CIS100_RHEL9_313.sh | 31 + .../ShellScripts/RHEL9/CIS100_RHEL9_321.sh | 34 + .../ShellScripts/RHEL9/CIS100_RHEL9_322_1.sh | 16 + .../ShellScripts/RHEL9/CIS100_RHEL9_322_2.sh | 15 + .../ShellScripts/RHEL9/CIS100_RHEL9_331_11.sh | 16 + .../ShellScripts/RHEL9/CIS100_RHEL9_331_12.sh | 16 + .../ShellScripts/RHEL9/CIS100_RHEL9_331_21.sh | 15 + .../ShellScripts/RHEL9/CIS100_RHEL9_331_22.sh | 15 + .../ShellScripts/RHEL9/CIS100_RHEL9_332_11.sh | 16 + .../ShellScripts/RHEL9/CIS100_RHEL9_332_12.sh | 15 + .../ShellScripts/RHEL9/CIS100_RHEL9_332_21.sh | 14 + .../ShellScripts/RHEL9/CIS100_RHEL9_332_22.sh | 15 + .../ShellScripts/RHEL9/CIS100_RHEL9_334_1.sh | 15 + .../ShellScripts/RHEL9/CIS100_RHEL9_334_2.sh | 16 + .../ShellScripts/RHEL9/CIS100_RHEL9_335.sh | 17 + .../ShellScripts/RHEL9/CIS100_RHEL9_336.sh | 15 + .../ShellScripts/RHEL9/CIS100_RHEL9_337_1.sh | 14 + .../ShellScripts/RHEL9/CIS100_RHEL9_337_2.sh | 16 + .../ShellScripts/RHEL9/CIS100_RHEL9_338.sh | 15 + .../ShellScripts/RHEL9/CIS100_RHEL9_339_1.sh | 15 + .../ShellScripts/RHEL9/CIS100_RHEL9_339_2.sh | 16 + .../ShellScripts/RHEL9/CIS100_RHEL9_3412.sh | 26 + .../ShellScripts/RHEL9/CIS100_RHEL9_3421.sh | 19 + .../RHEL9/CIS100_RHEL9_41310_1.sh | 5 + .../RHEL9/CIS100_RHEL9_41310_2.sh | 5 + .../RHEL9/CIS100_RHEL9_41313_1.sh | 5 + .../RHEL9/CIS100_RHEL9_41313_2.sh | 5 + .../RHEL9/CIS100_RHEL9_41314_1.sh | 4 + .../RHEL9/CIS100_RHEL9_41314_2.sh | 4 + .../RHEL9/CIS100_RHEL9_41315_1.sh | 5 + .../RHEL9/CIS100_RHEL9_41315_2.sh | 5 + .../RHEL9/CIS100_RHEL9_41316_1.sh | 5 + .../RHEL9/CIS100_RHEL9_41316_2.sh | 5 + .../RHEL9/CIS100_RHEL9_41317_1.sh | 5 + .../RHEL9/CIS100_RHEL9_41317_2.sh | 5 + .../RHEL9/CIS100_RHEL9_41318_1.sh | 5 + .../RHEL9/CIS100_RHEL9_41318_2.sh | 5 + .../RHEL9/CIS100_RHEL9_41319_1.sh | 6 + .../RHEL9/CIS100_RHEL9_41319_2.sh | 6 + .../ShellScripts/RHEL9/CIS100_RHEL9_4133_1.sh | 5 + .../ShellScripts/RHEL9/CIS100_RHEL9_4133_2.sh | 5 + .../ShellScripts/RHEL9/CIS100_RHEL9_4136_1.sh | 8 + .../ShellScripts/RHEL9/CIS100_RHEL9_4136_2.sh | 9 + .../ShellScripts/RHEL9/CIS100_RHEL9_4137_1.sh | 5 + .../ShellScripts/RHEL9/CIS100_RHEL9_4137_2.sh | 5 + .../ShellScripts/RHEL9/CIS100_RHEL9_4139_1.sh | 5 + .../ShellScripts/RHEL9/CIS100_RHEL9_4139_2.sh | 5 + .../ShellScripts/RHEL9/CIS100_RHEL9_4141.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_4142.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_4144.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_4145.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_522.sh | 30 + .../ShellScripts/RHEL9/CIS100_RHEL9_523.sh | 30 + .../ShellScripts/RHEL9/CIS100_RHEL9_5611_1.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_5611_2.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_5612_1.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_5612_2.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_5613_1.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_5613_2.sh | 9 + .../ShellScripts/RHEL9/CIS100_RHEL9_5614_1.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_5614_2.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_5615.sh | 9 + .../ShellScripts/RHEL9/CIS100_RHEL9_562_1.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_562_2.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_565_1.sh | 6 + .../ShellScripts/RHEL9/CIS100_RHEL9_565_2.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_621.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_6210.sh | 14 + .../ShellScripts/RHEL9/CIS100_RHEL9_6211.sh | 14 + .../ShellScripts/RHEL9/CIS100_RHEL9_6212.sh | 16 + .../ShellScripts/RHEL9/CIS100_RHEL9_6213.sh | 25 + .../ShellScripts/RHEL9/CIS100_RHEL9_6214.sh | 15 + .../ShellScripts/RHEL9/CIS100_RHEL9_6215.sh | 15 + .../ShellScripts/RHEL9/CIS100_RHEL9_6216.sh | 19 + .../ShellScripts/RHEL9/CIS100_RHEL9_622.sh | 4 + .../ShellScripts/RHEL9/CIS100_RHEL9_628.sh | 16 + .../ShellScripts/RHEL9/CIS100_RHEL9_629.sh | 4 + .../ShellScripts/RHEL9_CIS2.0.0/1.2.1.2.sh | 42 + .../ShellScripts/RHEL9_CIS2.0.0/1.3.1.2.sh | 7 + .../ShellScripts/RHEL9_CIS2.0.0/1.3.1.3.sh | 20 + .../ShellScripts/RHEL9_CIS2.0.0/1.3.1.5.sh | 7 + .../ShellScripts/RHEL9_CIS2.0.0/1.5.3.sh | 12 + .../ShellScripts/RHEL9_CIS2.0.0/1.5.4.sh | 12 + .../ShellScripts/RHEL9_CIS2.0.0/1.6.1.sh | 3 + .../ShellScripts/RHEL9_CIS2.0.0/1.6.2.sh | 13 + .../ShellScripts/RHEL9_CIS2.0.0/1.7.1.sh | 15 + .../ShellScripts/RHEL9_CIS2.0.0/1.7.4.sh | 11 + .../ShellScripts/RHEL9_CIS2.0.0/1.8.10.sh | 17 + .../ShellScripts/RHEL9_CIS2.0.0/1.8.2.sh | 52 + .../ShellScripts/RHEL9_CIS2.0.0/1.8.3.sh | 41 + .../ShellScripts/RHEL9_CIS2.0.0/1.8.4.sh | 55 + .../ShellScripts/RHEL9_CIS2.0.0/1.8.5.sh | 45 + .../ShellScripts/RHEL9_CIS2.0.0/1.8.6.sh | 61 + .../ShellScripts/RHEL9_CIS2.0.0/1.8.7.sh | 45 + .../ShellScripts/RHEL9_CIS2.0.0/1.8.8.sh | 53 + .../ShellScripts/RHEL9_CIS2.0.0/1.8.9.sh | 36 + .../ShellScripts/RHEL9_CIS2.0.0/2.3.3.sh | 18 + .../ShellScripts/RHEL9_CIS2.0.0/2.4.18.sh | 44 + .../ShellScripts/RHEL9_CIS2.0.0/3.1.3.sh | 31 + .../ShellScripts/RHEL9_CIS2.0.0/4.1.2.sh | 26 + .../ShellScripts/RHEL9_CIS2.0.0/5.1.10.sh | 28 + .../ShellScripts/RHEL9_CIS2.0.0/5.1.11.sh | 28 + .../ShellScripts/RHEL9_CIS2.0.0/5.1.12.sh | 27 + .../ShellScripts/RHEL9_CIS2.0.0/5.1.13.sh | 28 + .../ShellScripts/RHEL9_CIS2.0.0/5.1.14.sh | 29 + .../ShellScripts/RHEL9_CIS2.0.0/5.1.15.sh | 28 + .../ShellScripts/RHEL9_CIS2.0.0/5.1.17.sh | 27 + .../ShellScripts/RHEL9_CIS2.0.0/5.1.18.sh | 29 + .../ShellScripts/RHEL9_CIS2.0.0/5.1.9.sh | 34 + .../ShellScripts/RHEL9_CIS2.0.0/5.3.2.2.sh | 39 + .../ShellScripts/RHEL9_CIS2.0.0/5.3.2.3.sh | 32 + .../ShellScripts/RHEL9_CIS2.0.0/5.3.2.4.sh | 45 + .../ShellScripts/RHEL9_CIS2.0.0/5.3.2.5.sh | 31 + .../ShellScripts/RHEL9_CIS2.0.0/5.3.3.2.7.sh | 30 + .../ShellScripts/RHEL9_CIS2.0.0/5.3.3.3.1.sh | 17 + .../ShellScripts/RHEL9_CIS2.0.0/5.3.3.3.2.sh | 15 + .../ShellScripts/RHEL9_CIS2.0.0/5.3.3.4.2.sh | 24 + .../ShellScripts/RHEL9_CIS2.0.0/5.3.3.4.3.sh | 29 + .../ShellScripts/RHEL9_CIS2.0.0/5.4.1.6.sh | 9 + .../ShellScripts/RHEL9_CIS2.0.0/5.4.2.1.sh | 4 + .../ShellScripts/RHEL9_CIS2.0.0/5.4.2.5.sh | 16 + .../ShellScripts/RHEL9_CIS2.0.0/6.2.2.1.4.sh | 13 + .../ShellScripts/RHEL9_CIS2.0.0/6.2.2.2.sh | 16 + .../ShellScripts/RHEL9_CIS2.0.0/6.2.2.3.sh | 16 + .../ShellScripts/RHEL9_CIS2.0.0/6.2.2.4.sh | 16 + .../ShellScripts/RHEL9_CIS2.0.0/6.2.3.4.sh | 24 + .../ShellScripts/RHEL9_CIS2.0.0/6.2.3.7.sh | 23 + .../ShellScripts/RHEL9_CIS2.0.0/6.3.1.2.sh | 15 + .../ShellScripts/RHEL9_CIS2.0.0/6.3.1.3.sh | 15 + .../ShellScripts/RHEL9_CIS2.0.0/6.3.4.1.sh | 17 + .../ShellScripts/RHEL9_CIS2.0.0/6.3.4.2.sh | 29 + .../ShellScripts/RHEL9_CIS2.0.0/6.3.4.3.sh | 23 + .../ShellScripts/RHEL9_CIS2.0.0/6.3.4.4.sh | 27 + .../ShellScripts/RHEL9_CIS2.0.0/7.2.1.sh | 4 + .../ShellScripts/RHEL9_CIS2.0.0/7.2.2.sh | 4 + .../ShellScripts/SLE_15/CIS-SEL15-1.8.1.3.sh | 2 + .../ShellScripts/SLE_15/CIS-SEL15-5.4.2_1.sh | 2 + .../ShellScripts/SLE_15/CIS-SEL15-5.4.2_2.sh | 2 + .../ShellScripts/SLE_15/CIS-SEL15-5.4.4.sh | 4 + .../ShellScripts/SLE_15/CIS-SEL15-6.2.1.sh | 2 + .../ShellScripts/SLE_15/CIS-SEL15-6.2.10.sh | 10 + .../ShellScripts/SLE_15/CIS-SEL15-6.2.11.sh | 30 + .../ShellScripts/SLE_15/CIS-SEL15-6.2.12.sh | 12 + .../ShellScripts/SLE_15/CIS-SEL15-6.2.18_1.sh | 2 + .../ShellScripts/SLE_15/CIS-SEL15-6.2.18_2.sh | 2 + .../ShellScripts/SLE_15/CIS-SEL15-6.2.2.sh | 2 + .../ShellScripts/SLE_15/CIS-SEL15-6.2.5.sh | 6 + .../ShellScripts/SLE_15/CIS-SEL15-6.2.6.sh | 20 + .../ShellScripts/SLE_15/CIS-SEL15-6.2.7.sh | 11 + .../ShellScripts/SLE_15/CIS-SEL15-6.2.8.sh | 18 + .../ShellScripts/SLE_15/CIS-SEL15-6.2.9.sh | 10 + .../Ubuntu22.04_Debian12/1.1.2.2.1.sh | 5 + .../Ubuntu22.04_Debian12/1.3.1.2.sh | 15 + .../Ubuntu22.04_Debian12/1.3.1.4.sh | 10 + .../Ubuntu22.04_Debian12/1.5.3.sh | 23 + .../Ubuntu22.04_Debian12/1.6.1.sh | 15 + .../Ubuntu22.04_Debian12/1.6.4.sh | 11 + .../Ubuntu22.04_Debian12/1.7.10.sh | 17 + .../Ubuntu22.04_Debian12/1.8.2.sh | 32 + .../Ubuntu22.04_Debian12/1.8.3.sh | 28 + .../Ubuntu22.04_Debian12/1.8.4.sh | 17 + .../Ubuntu22.04_Debian12/1.8.5.sh | 30 + .../Ubuntu22.04_Debian12/1.8.6.sh | 10 + .../Ubuntu22.04_Debian12/1.8.7.sh | 30 + .../Ubuntu22.04_Debian12/1.8.8.sh | 7 + .../Ubuntu22.04_Debian12/1.8.9.sh | 29 + .../Ubuntu22.04_Debian12/2.1.1.1.sh | 30 + .../Ubuntu22.04_Debian12/2.3.3.2.sh | 16 + .../Ubuntu22.04_Debian12/3.1.1.sh | 22 + .../Ubuntu22.04_Debian12/3.5.1.6.sh | 8 + .../Ubuntu22.04_Debian12/3.5.2.10_1.sh | 2 + .../Ubuntu22.04_Debian12/3.5.2.10_2.sh | 2 + .../Ubuntu22.04_Debian12/3.5.2.10_3.sh | 2 + .../Ubuntu22.04_Debian12/4.1.3.11_1.sh | 10 + .../Ubuntu22.04_Debian12/4.1.3.11_2.sh | 9 + .../Ubuntu22.04_Debian12/4.2.3.sh | 11 + .../Ubuntu22.04_Debian12/5.1.10.sh | 27 + .../Ubuntu22.04_Debian12/5.1.11.sh | 28 + .../Ubuntu22.04_Debian12/5.1.12.sh | 9 + .../Ubuntu22.04_Debian12/5.1.13.sh | 29 + .../Ubuntu22.04_Debian12/5.1.14.sh | 28 + .../Ubuntu22.04_Debian12/5.1.15.sh | 14 + .../Ubuntu22.04_Debian12/5.1.17.sh | 29 + .../Ubuntu22.04_Debian12/5.1.18.sh | 27 + .../Ubuntu22.04_Debian12/5.1.6.sh | 15 + .../Ubuntu22.04_Debian12/5.1.7.sh | 34 + .../Ubuntu22.04_Debian12/5.1.8.sh | 28 + .../Ubuntu22.04_Debian12/5.1.9.sh | 28 + .../Ubuntu22.04_Debian12/5.2.4.sh | 16 + .../Ubuntu22.04_Debian12/5.2.5.sh | 15 + .../Ubuntu22.04_Debian12/5.2.7.sh | 12 + .../Ubuntu22.04_Debian12/5.3.2.1.sh | 23 + .../Ubuntu22.04_Debian12/5.3.2.2.sh | 40 + .../Ubuntu22.04_Debian12/5.3.2.3.sh | 32 + .../Ubuntu22.04_Debian12/5.3.2.4.sh | 30 + .../Ubuntu22.04_Debian12/5.3.3.2.7.sh | 17 + .../Ubuntu22.04_Debian12/5.3.3.2.8.sh | 30 + .../Ubuntu22.04_Debian12/5.3.3.3.1.sh | 18 + .../Ubuntu22.04_Debian12/5.3.3.3.2.sh | 15 + .../Ubuntu22.04_Debian12/5.3.3.4.2.sh | 8 + .../Ubuntu22.04_Debian12/5.3.3.4.3.sh | 14 + .../Ubuntu22.04_Debian12/5.4.2.4.sh | 10 + .../Ubuntu22.04_Debian12/5.5.1.5.sh | 9 + .../Ubuntu22.04_Debian12/6.2.1.1.4.sh | 16 + .../Ubuntu22.04_Debian12/6.2.1.1.5.sh | 16 + .../Ubuntu22.04_Debian12/6.2.1.1.6.sh | 16 + .../Ubuntu22.04_Debian12/6.2.1.2.4.sh | 13 + .../Ubuntu22.04_Debian12/6.2.3.sh | 5 + .../Ubuntu22.04_Debian12/6.2.5.sh | 10 + .../Ubuntu22.04_Debian12/6.2.6.sh | 5 + .../Ubuntu22.04_Debian12/6.2.7.sh | 5 + .../Ubuntu22.04_Debian12/6.2.8.sh | 5 + .../Ubuntu22.04_Debian12/6.2.9.sh | 9 + .../Ubuntu22.04_Debian12/6.3.1.3.sh | 15 + .../Ubuntu22.04_Debian12/6.3.1.4.sh | 15 + .../Ubuntu22.04_Debian12/6.3.4.1.sh | 29 + .../Ubuntu22.04_Debian12/6.3.4.2.sh | 23 + .../Ubuntu22.04_Debian12/6.3.4.3.sh | 27 + .../Ubuntu22.04_Debian12/6.3.4.4.sh | 17 + .../Helpers/ShellScripts/common/1.1.1.1.sh | 58 + .../Helpers/ShellScripts/common/1.1.1.2.sh | 59 + .../Helpers/ShellScripts/common/1.1.1.3.sh | 58 + .../Helpers/ShellScripts/common/1.1.1.4.sh | 58 + .../Helpers/ShellScripts/common/1.1.1.5.sh | 58 + .../Helpers/ShellScripts/common/1.1.1.6.sh | 63 + .../Helpers/ShellScripts/common/1.1.1.7.sh | 58 + .../Helpers/ShellScripts/common/1.1.1.8.sh | 59 + .../Helpers/ShellScripts/common/1.1.2.1.2.sh | 9 + .../Helpers/ShellScripts/common/1.1.2.1.3.sh | 11 + .../Helpers/ShellScripts/common/1.1.2.2.2.sh | 18 + .../Helpers/ShellScripts/common/1.1.2.2.3.sh | 18 + .../Helpers/ShellScripts/common/1.1.2.2.4.sh | 18 + .../Helpers/ShellScripts/common/1.1.2.3.2.sh | 18 + .../Helpers/ShellScripts/common/1.1.2.3.3.sh | 9 + .../Helpers/ShellScripts/common/1.1.2.4.2.sh | 11 + .../Helpers/ShellScripts/common/1.1.2.4.3.sh | 11 + .../Helpers/ShellScripts/common/1.1.2.5.2.sh | 18 + .../Helpers/ShellScripts/common/1.1.2.5.3.sh | 18 + .../Helpers/ShellScripts/common/1.1.2.5.4.sh | 18 + .../Helpers/ShellScripts/common/1.1.2.6.2.sh | 18 + .../Helpers/ShellScripts/common/1.1.2.6.3.sh | 18 + .../Helpers/ShellScripts/common/1.1.2.6.4.sh | 18 + .../Helpers/ShellScripts/common/1.1.2.7.2.sh | 18 + .../Helpers/ShellScripts/common/1.1.2.7.3.sh | 18 + .../Helpers/ShellScripts/common/1.1.2.7.4.sh | 18 + .../Helpers/ShellScripts/common/1.4.2.sh | 31 + .../Helpers/ShellScripts/common/1.5.1.sh | 19 + .../Helpers/ShellScripts/common/1.5.2.sh | 18 + .../Helpers/ShellScripts/common/2.1.13.sh | 15 + .../Helpers/ShellScripts/common/2.4.1.8.sh | 44 + .../Helpers/ShellScripts/common/2.4.2.1.sh | 43 + .../Helpers/ShellScripts/common/3.1.2.sh | 43 + .../Helpers/ShellScripts/common/3.2.1.sh | 58 + .../Helpers/ShellScripts/common/3.2.2.sh | 58 + .../Helpers/ShellScripts/common/3.2.3.sh | 58 + .../Helpers/ShellScripts/common/3.2.4.sh | 58 + .../Helpers/ShellScripts/common/3.3.1.sh | 23 + .../Helpers/ShellScripts/common/3.3.10.sh | 18 + .../Helpers/ShellScripts/common/3.3.11.sh | 24 + .../Helpers/ShellScripts/common/3.3.2.sh | 24 + .../Helpers/ShellScripts/common/3.3.3.sh | 18 + .../Helpers/ShellScripts/common/3.3.4.sh | 19 + .../Helpers/ShellScripts/common/3.3.5.sh | 24 + .../Helpers/ShellScripts/common/3.3.6.sh | 24 + .../Helpers/ShellScripts/common/3.3.7.sh | 24 + .../Helpers/ShellScripts/common/3.3.8.sh | 24 + .../Helpers/ShellScripts/common/3.3.9.sh | 24 + .../Helpers/ShellScripts/common/5.1.16.sh | 28 + .../Helpers/ShellScripts/common/5.1.19.sh | 27 + .../Helpers/ShellScripts/common/5.1.20.sh | 28 + .../Helpers/ShellScripts/common/5.1.21.sh | 26 + .../Helpers/ShellScripts/common/5.1.22.sh | 28 + .../Helpers/ShellScripts/common/5.1.3.sh | 13 + .../Helpers/ShellScripts/common/5.2.2.sh | 11 + .../Helpers/ShellScripts/common/5.2.3.sh | 10 + .../Helpers/ShellScripts/common/5.2.6.sh | 23 + .../Helpers/ShellScripts/common/5.3.3.1.1.sh | 16 + .../Helpers/ShellScripts/common/5.3.3.1.2.sh | 23 + .../Helpers/ShellScripts/common/5.3.3.1.3.sh | 24 + .../Helpers/ShellScripts/common/5.3.3.2.1.sh | 49 + .../Helpers/ShellScripts/common/5.3.3.2.2.sh | 49 + .../Helpers/ShellScripts/common/5.3.3.2.4.sh | 48 + .../Helpers/ShellScripts/common/5.3.3.2.5.sh | 49 + .../Helpers/ShellScripts/common/5.3.3.2.6.sh | 48 + .../Helpers/ShellScripts/common/5.3.3.3.3.sh | 15 + .../Helpers/ShellScripts/common/5.3.3.4.1.sh | 8 + .../Helpers/ShellScripts/common/5.3.3.4.4.sh | 15 + .../Helpers/ShellScripts/common/5.4.1.1.sh | 49 + .../Helpers/ShellScripts/common/5.4.1.2.sh | 48 + .../Helpers/ShellScripts/common/5.4.1.3.sh | 48 + .../Helpers/ShellScripts/common/5.4.1.4.sh | 55 + .../Helpers/ShellScripts/common/5.4.1.5.sh | 22 + .../Helpers/ShellScripts/common/5.4.2.3.sh | 17 + .../Helpers/ShellScripts/common/5.4.2.6.sh | 10 + .../Helpers/ShellScripts/common/5.4.2.7.sh | 20 + .../Helpers/ShellScripts/common/5.4.2.8.sh | 8 + .../Helpers/ShellScripts/common/5.4.3.1.sh | 23 + .../Helpers/ShellScripts/common/5.4.3.2.sh | 8 + .../Helpers/ShellScripts/common/5.4.3.3.sh | 9 + .../Helpers/ShellScripts/common/6.1.3.sh | 15 + .../Helpers/ShellScripts/common/6.3.2.1.sh | 17 + .../Helpers/ShellScripts/common/6.3.2.2.sh | 17 + .../Helpers/ShellScripts/common/6.3.3.1.sh | 10 + .../Helpers/ShellScripts/common/6.3.3.10.sh | 16 + .../Helpers/ShellScripts/common/6.3.3.12.sh | 10 + .../Helpers/ShellScripts/common/6.3.3.13.sh | 16 + .../Helpers/ShellScripts/common/6.3.3.14.sh | 10 + .../Helpers/ShellScripts/common/6.3.3.15.sh | 16 + .../Helpers/ShellScripts/common/6.3.3.16.sh | 16 + .../Helpers/ShellScripts/common/6.3.3.17.sh | 16 + .../Helpers/ShellScripts/common/6.3.3.18.sh | 16 + .../Helpers/ShellScripts/common/6.3.3.19.sh | 17 + .../Helpers/ShellScripts/common/6.3.3.2.sh | 10 + .../Helpers/ShellScripts/common/6.3.3.3.sh | 18 + .../Helpers/ShellScripts/common/6.3.3.4.sh | 11 + .../Helpers/ShellScripts/common/6.3.3.5.sh | 11 + .../Helpers/ShellScripts/common/6.3.3.6.sh | 38 + .../Helpers/ShellScripts/common/6.3.3.7.sh | 15 + .../Helpers/ShellScripts/common/6.3.3.8.sh | 12 + .../Helpers/ShellScripts/common/6.3.3.9.sh | 16 + .../Helpers/ShellScripts/common/6.3.4.5.sh | 28 + .../Helpers/ShellScripts/common/6.3.4.6.sh | 10 + .../Helpers/ShellScripts/common/6.3.4.7.sh | 11 + .../Helpers/ShellScripts/common/6.3.4.8.sh | 20 + .../Helpers/ShellScripts/common/6.3.4.9.sh | 24 + .../Helpers/ShellScripts/common/7.1.10.sh | 13 + .../Helpers/ShellScripts/common/7.1.11.sh | 31 + .../Helpers/ShellScripts/common/7.1.12.sh | 21 + .../Helpers/ShellScripts/common/7.1.9.sh | 18 + ATAPAuditor/Reports/Debian 10.ps1 | 19 + ATAPAuditor/Reports/Debian 11.ps1 | 19 + ATAPAuditor/Reports/Debian 12.ps1 | 19 + ATAPAuditor/Reports/Fedora 35.ps1 | 19 + ATAPAuditor/Reports/Google Chrome.ps1 | 30 + ATAPAuditor/Reports/Microsoft Edge.ps1 | 30 + ATAPAuditor/Reports/Microsoft IIS10.ps1 | 2915 +++ .../Microsoft Internet Explorer 11.ps1 | 41 + ATAPAuditor/Reports/Microsoft Office.ps1 | 19 + .../Reports/Microsoft SQL Server 2016.ps1 | 2754 +++ .../Reports/Microsoft Windows 10 BSI.ps1 | 114 + .../Reports/Microsoft Windows 10 GDPR.ps1 | 50 + .../Microsoft Windows 10 Stand-alone.ps1 | 103 + ATAPAuditor/Reports/Microsoft Windows 10.ps1 | 199 + .../Microsoft Windows 11 Stand-alone.ps1 | 103 + ATAPAuditor/Reports/Microsoft Windows 11.ps1 | 168 + ATAPAuditor/Reports/Microsoft Windows 7.ps1 | 47 + .../Reports/Microsoft Windows Server 2012.ps1 | 76 + .../Reports/Microsoft Windows Server 2016.ps1 | 102 + .../Reports/Microsoft Windows Server 2019.ps1 | 106 + .../Reports/Microsoft Windows Server 2022.ps1 | 106 + .../Reports/Microsoft Windows Server 2025.ps1 | 38 + ATAPAuditor/Reports/Mozilla Firefox.ps1 | 873 + .../Reports/Red Hat Enterprise Linux 9.ps1 | 19 + ATAPAuditor/Reports/SUSE 15.ps1 | 19 + ATAPAuditor/Reports/Ubuntu 20.04.ps1 | 19 + ATAPAuditor/Reports/Ubuntu 22.04.ps1 | 19 + ATAPAuditor/Resources/FirefoxPreferences.ps1 | 134 + .../Resources/WindowsSecurityPolicy.ps1 | 48 + ATAPHtmlReport/ATAPHtmlReport.Tests.ps1 | 91 + ATAPHtmlReport/ATAPHtmlReport.psd1 | 146 + ATAPHtmlReport/ATAPHtmlReport.psm1 | 2125 ++ ATAPHtmlReport/README.md | 105 + ATAPHtmlReport/Settings.psd1 | 57 + .../Tests/Compare-EqualCISVersions.Tests.ps1 | 224 + .../Tests/ConvertTo-HtmlTable.Tests.ps1 | 50 + ATAPHtmlReport/Tests/Get-ColorValue.Tests.ps1 | 55 + .../Get-MitigationsFromFailedTests.Tests.ps1 | 419 + .../Tests/Get-MitreTacticName.Tests.ps1 | 12 + .../Tests/Get-MitreTactics.Tests.ps1 | 13 + .../Tests/Get-MitreTechniqueName.Tests.ps1 | 17 + .../Tests/Get-TacticCounter.Tests.ps1 | 71 + .../Tests/Merge-CisAuditsToMitreMap.Tests.ps1 | 50 + ATAPHtmlReport/Tests/MitreMap.Tests.ps1 | 101 + ATAPHtmlReport/Tests/OrderTactics.Test.ps1 | 43 + .../Test-CompatibleMitreReport.Tests.ps1 | 24 + ATAPHtmlReport/Tests/get-MitreLink.Tests.ps1 | 20 + ATAPHtmlReport/Tests/readFromJson.Tests.ps1 | 73 + ATAPHtmlReport/Tests/updateATAP.ps1 | 16 + ATAPHtmlReport/report.css | 1203 + ATAPHtmlReport/report.js | 278 + .../resources/CISToAttackMappingData.json | Bin 0 -> 518728 bytes ATAPHtmlReport/runATAP.ps1 | 42 + FAQ/images/FAQ_print backgrounds.PNG | Bin 0 -> 4521 bytes FAQ/images/readme.md | 1 + FAQ/readme.md | 51 + Installer/.gitignore | 2 + Installer/LICENSE | 29 + Installer/icons/AT.ico | Bin 0 -> 68249 bytes Installer/icons/AT1024.png | Bin 0 -> 20808 bytes Installer/icons/AT1024_source.xcf | Bin 0 -> 66611 bytes Installer/icons/AT128.png | Bin 0 -> 2620 bytes Installer/icons/AT16.png | Bin 0 -> 904 bytes Installer/icons/AT256.png | Bin 0 -> 4975 bytes Installer/icons/AT32.png | Bin 0 -> 1136 bytes Installer/icons/AT512.png | Bin 0 -> 10773 bytes Installer/icons/AT64.png | Bin 0 -> 1552 bytes Installer/setup.exe | Bin 0 -> 3056004 bytes LICENSE | 29 + Samples/Google Chrome_20220902_134320.html | 15 + Samples/Microsoft IIS10_20220905_052811.html | 21 + Samples/Microsoft Windows 10 All.html | 35 + .../Microsoft Windows 10 All_RiskScore.html | 35 + ...rosoft Windows 10 BSI_20220905_134713.html | 30 + ...t Windows Server 2022_20220905_052544.html | 18 + Samples/Outdated/Debian 10.html | 12 + Samples/Outdated/GoogleChrome.dark.html | 1 + Samples/Outdated/GoogleChrome.html | 1 + .../Microsoft Windows 10 BSI Dark.html | 28 + .../Outdated/Microsoft Windows 10 BSI.html | 28 + .../Outdated/Microsoft Windows 11 Dark.html | 14 + Samples/Outdated/Microsoft Windows 11.html | 14 + Samples/Outdated/MozillaFirefox.dark.html | 1 + Samples/Outdated/MozillaFirefox.html | 1 + Samples/Outdated/Office2016.dark.html | 1 + Samples/Outdated/Office2016Excel.dark.html | 1 + Samples/Outdated/Office2016Outlook.dark.html | 1 + Samples/Outdated/Office2016Outlook.html | 1 + .../Outdated/Office2016PowerPoint.dark.html | 1 + Samples/Outdated/Office2016PowerPoint.html | 1 + .../Office2016SkypeForBusiness.dark.html | 1 + .../Outdated/Office2016SkypeForBusiness.html | 1 + Samples/Outdated/Office2016Word.dark.html | 1 + Samples/Outdated/Office2016Word.html | 1 + Samples/Outdated/Windows10.html | 14 + 641 files changed, 416825 insertions(+) create mode 100644 .gitignore create mode 100644 ATAPAuditor/ATAPAuditor.psd1 create mode 100644 ATAPAuditor/ATAPAuditor.psm1 create mode 100644 ATAPAuditor/AuditGroups/CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Debian Linux 11-CIS-1.0.0.ps1 create mode 100644 ATAPAuditor/AuditGroups/Debian Linux 12-CIS-1.0.1.ps1 create mode 100644 ATAPAuditor/AuditGroups/Enhanced security settings-FBPro-1.0#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Google Chrome-CIS-2.0.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Google Chrome-DISA-V1R15#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Edge-CIS-2.0.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Edge-Microsoft-117#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Internet Explorer 11-CIS-1.0.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Internet Explorer 11-DISA-V1R16#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Internet Explorer 11-MS-2004#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Office Enterprise-CIS-1.2.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 GDPR-MS-16082019#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHus-Telemetrie-BSI-V1.2#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 7-CIS-3.1.0#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 7-CIS-3.1.0#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows 7-CIS-3.1.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-DISA-V2R19#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-DISA-V2R19#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-DISA-V2R19#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-1.12#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#AccountPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#AuditPolicies.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#RegistrySettings.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#SecurityOptions.ps1 create mode 100644 ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#UserRights.ps1 create mode 100644 ATAPAuditor/AuditGroups/RSSeverityTests.ps1 create mode 100644 ATAPAuditor/AuditGroups/Red Hat Enterprise Linux 9-CIS-1.0.0.ps1 create mode 100644 ATAPAuditor/AuditGroups/Red Hat Enterprise Linux 9-CIS-2.0.0.ps1 create mode 100644 ATAPAuditor/AuditGroups/SBD - Application Control.ps1 create mode 100644 ATAPAuditor/AuditGroups/SBD - Connectivity Security.ps1 create mode 100644 ATAPAuditor/AuditGroups/SBD - Linux Base Security.ps1 create mode 100644 ATAPAuditor/AuditGroups/SBD - Platform Security.ps1 create mode 100644 ATAPAuditor/AuditGroups/SBD - PowerShell Security.ps1 create mode 100644 ATAPAuditor/AuditGroups/SBD - Windows Base Security.ps1 create mode 100644 ATAPAuditor/AuditGroups/SUSE Linux Enterprise 15-CIS-1.1.1.ps1 create mode 100644 ATAPAuditor/AuditGroups/Ubuntu Linux 20.04-CIS-1.1.0.ps1 create mode 100644 ATAPAuditor/AuditGroups/Ubuntu Linux 22.04-CIS-2.0.0.ps1 create mode 100644 ATAPAuditor/Helpers/AuditGroupFunctions.ps1 create mode 100644 ATAPAuditor/Helpers/Firewall.ps1 create mode 100644 ATAPAuditor/Helpers/HashHelper.ps1 create mode 100644 ATAPAuditor/Helpers/LinuxHelper.ps1 create mode 100644 ATAPAuditor/Helpers/LogFile.ps1 create mode 100644 ATAPAuditor/Helpers/Menu.ps1 create mode 100644 ATAPAuditor/Helpers/ReportUnixOS.ps1 create mode 100644 ATAPAuditor/Helpers/ReportWindowsOS.ps1 create mode 100644 ATAPAuditor/Helpers/SecurityPolicy.psm1 create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.10.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.5.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.9.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-2.1.1.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.2.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.2.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.9.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.5.1.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.3.6-A.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.3.6-B.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.2.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.2.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.4.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.1.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.11.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.12.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.13.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.14.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.15.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.16.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.17.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.9.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_1111.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_1112.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_119.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_182.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_183.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_184.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_185.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_186.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_187.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_188.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_189.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_312.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_313.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_321.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_322_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_322_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_11.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_12.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_21.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_22.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_11.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_12.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_21.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_22.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_334_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_334_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_335.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_336.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_337_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_337_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_338.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_339_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_339_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_3412.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_3421.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41310_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41310_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41313_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41313_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41314_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41314_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41315_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41315_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41316_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41316_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41317_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41317_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41318_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41318_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41319_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41319_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4133_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4133_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4136_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4136_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4137_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4137_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4139_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4139_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4141.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4142.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4144.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4145.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_522.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_523.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5611_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5611_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5612_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5612_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5613_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5613_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5614_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5614_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5615.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_562_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_562_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_565_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_565_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_621.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6210.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6211.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6212.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6213.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6214.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6215.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6216.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_622.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_628.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_629.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.2.1.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.3.1.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.3.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.3.1.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.5.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.5.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.6.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.6.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.7.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.7.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.10.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.9.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/2.3.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/2.4.18.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/3.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/4.1.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.10.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.11.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.12.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.13.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.14.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.15.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.17.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.18.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.9.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.2.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.3.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.3.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.4.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.4.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.4.1.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.4.2.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.4.2.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.1.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.3.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.3.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.1.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/7.2.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/7.2.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-1.8.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-5.4.2_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-5.4.2_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-5.4.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.10.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.11.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.12.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.18_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.18_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.9.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.1.2.2.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.3.1.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.3.1.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.5.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.6.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.6.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.7.10.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.9.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/2.1.1.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/2.3.3.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.1.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.1.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.2.10_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.2.10_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.2.10_3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/4.1.3.11_1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/4.1.3.11_2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/4.2.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.10.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.11.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.12.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.13.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.14.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.15.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.17.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.18.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.9.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.2.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.2.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.2.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.2.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.2.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.3.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.3.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.4.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.4.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.4.2.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.5.1.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.1.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.1.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.1.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.2.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.9.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.1.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.1.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.1.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.1.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.1.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.1.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.1.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.1.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.1.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.2.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.2.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.2.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.3.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.3.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.4.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.4.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.5.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.5.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.5.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.6.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.6.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.6.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.7.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.7.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.1.2.7.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.4.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.5.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/1.5.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/2.1.13.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/2.4.1.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/2.4.2.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.1.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.2.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.2.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.2.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.2.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.3.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.3.10.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.3.11.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.3.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.3.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.3.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.3.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.3.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.3.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.3.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/3.3.9.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.1.16.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.1.19.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.1.20.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.1.21.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.1.22.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.2.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.2.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.2.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.3.3.1.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.3.3.1.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.3.3.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.3.3.3.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.3.3.4.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.3.3.4.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.4.1.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.4.1.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.4.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.4.1.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.4.1.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.4.2.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.4.2.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.4.2.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.4.2.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.4.3.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.4.3.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/5.4.3.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.1.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.2.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.2.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.1.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.10.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.12.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.13.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.14.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.15.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.16.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.17.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.18.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.19.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.2.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.3.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.4.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.3.9.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.4.5.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.4.6.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.4.7.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.4.8.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/6.3.4.9.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/7.1.10.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/7.1.11.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/7.1.12.sh create mode 100644 ATAPAuditor/Helpers/ShellScripts/common/7.1.9.sh create mode 100644 ATAPAuditor/Reports/Debian 10.ps1 create mode 100644 ATAPAuditor/Reports/Debian 11.ps1 create mode 100644 ATAPAuditor/Reports/Debian 12.ps1 create mode 100644 ATAPAuditor/Reports/Fedora 35.ps1 create mode 100644 ATAPAuditor/Reports/Google Chrome.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Edge.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft IIS10.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Internet Explorer 11.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Office.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft SQL Server 2016.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Windows 10 BSI.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Windows 10 GDPR.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Windows 10 Stand-alone.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Windows 10.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Windows 11 Stand-alone.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Windows 11.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Windows 7.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Windows Server 2012.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Windows Server 2016.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Windows Server 2019.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Windows Server 2022.ps1 create mode 100644 ATAPAuditor/Reports/Microsoft Windows Server 2025.ps1 create mode 100644 ATAPAuditor/Reports/Mozilla Firefox.ps1 create mode 100644 ATAPAuditor/Reports/Red Hat Enterprise Linux 9.ps1 create mode 100644 ATAPAuditor/Reports/SUSE 15.ps1 create mode 100644 ATAPAuditor/Reports/Ubuntu 20.04.ps1 create mode 100644 ATAPAuditor/Reports/Ubuntu 22.04.ps1 create mode 100644 ATAPAuditor/Resources/FirefoxPreferences.ps1 create mode 100644 ATAPAuditor/Resources/WindowsSecurityPolicy.ps1 create mode 100644 ATAPHtmlReport/ATAPHtmlReport.Tests.ps1 create mode 100644 ATAPHtmlReport/ATAPHtmlReport.psd1 create mode 100644 ATAPHtmlReport/ATAPHtmlReport.psm1 create mode 100644 ATAPHtmlReport/README.md create mode 100644 ATAPHtmlReport/Settings.psd1 create mode 100644 ATAPHtmlReport/Tests/Compare-EqualCISVersions.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/ConvertTo-HtmlTable.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/Get-ColorValue.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/Get-MitigationsFromFailedTests.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/Get-MitreTacticName.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/Get-MitreTactics.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/Get-MitreTechniqueName.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/Get-TacticCounter.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/Merge-CisAuditsToMitreMap.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/MitreMap.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/OrderTactics.Test.ps1 create mode 100644 ATAPHtmlReport/Tests/Test-CompatibleMitreReport.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/get-MitreLink.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/readFromJson.Tests.ps1 create mode 100644 ATAPHtmlReport/Tests/updateATAP.ps1 create mode 100644 ATAPHtmlReport/report.css create mode 100644 ATAPHtmlReport/report.js create mode 100644 ATAPHtmlReport/resources/CISToAttackMappingData.json create mode 100644 ATAPHtmlReport/runATAP.ps1 create mode 100644 FAQ/images/FAQ_print backgrounds.PNG create mode 100644 FAQ/images/readme.md create mode 100644 FAQ/readme.md create mode 100644 Installer/.gitignore create mode 100644 Installer/LICENSE create mode 100644 Installer/icons/AT.ico create mode 100644 Installer/icons/AT1024.png create mode 100644 Installer/icons/AT1024_source.xcf create mode 100644 Installer/icons/AT128.png create mode 100644 Installer/icons/AT16.png create mode 100644 Installer/icons/AT256.png create mode 100644 Installer/icons/AT32.png create mode 100644 Installer/icons/AT512.png create mode 100644 Installer/icons/AT64.png create mode 100644 Installer/setup.exe create mode 100644 LICENSE create mode 100644 Samples/Google Chrome_20220902_134320.html create mode 100644 Samples/Microsoft IIS10_20220905_052811.html create mode 100644 Samples/Microsoft Windows 10 All.html create mode 100644 Samples/Microsoft Windows 10 All_RiskScore.html create mode 100644 Samples/Microsoft Windows 10 BSI_20220905_134713.html create mode 100644 Samples/Microsoft Windows Server 2022_20220905_052544.html create mode 100644 Samples/Outdated/Debian 10.html create mode 100644 Samples/Outdated/GoogleChrome.dark.html create mode 100644 Samples/Outdated/GoogleChrome.html create mode 100644 Samples/Outdated/Microsoft Windows 10 BSI Dark.html create mode 100644 Samples/Outdated/Microsoft Windows 10 BSI.html create mode 100644 Samples/Outdated/Microsoft Windows 11 Dark.html create mode 100644 Samples/Outdated/Microsoft Windows 11.html create mode 100644 Samples/Outdated/MozillaFirefox.dark.html create mode 100644 Samples/Outdated/MozillaFirefox.html create mode 100644 Samples/Outdated/Office2016.dark.html create mode 100644 Samples/Outdated/Office2016Excel.dark.html create mode 100644 Samples/Outdated/Office2016Outlook.dark.html create mode 100644 Samples/Outdated/Office2016Outlook.html create mode 100644 Samples/Outdated/Office2016PowerPoint.dark.html create mode 100644 Samples/Outdated/Office2016PowerPoint.html create mode 100644 Samples/Outdated/Office2016SkypeForBusiness.dark.html create mode 100644 Samples/Outdated/Office2016SkypeForBusiness.html create mode 100644 Samples/Outdated/Office2016Word.dark.html create mode 100644 Samples/Outdated/Office2016Word.html create mode 100644 Samples/Outdated/Windows10.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..307833f --- /dev/null +++ b/.gitignore @@ -0,0 +1,336 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Visual Studio Code +.vscode/ + +# Custom +*/testreport.html \ No newline at end of file diff --git a/ATAPAuditor/ATAPAuditor.psd1 b/ATAPAuditor/ATAPAuditor.psd1 new file mode 100644 index 0000000..1dc77cf --- /dev/null +++ b/ATAPAuditor/ATAPAuditor.psd1 @@ -0,0 +1,45 @@ +@{ +RootModule = 'ATAPAuditor.psm1' +ModuleVersion = '5.12.1' +GUID = '1662a599-4e3a-4f72-a844-9582077b589e' +Author = 'Phan Quang Nguyen, Daniel Ströher, Robin Wernz' +CompanyName = 'FB Pro GmbH' +Copyright = '(c) 2025 FB Pro GmbH. All rights reserved.' +Description = 'AuditTAP allows you to check operating systems and applications against industry approved standards for secure configuration and delivers the results in form of a HTML based report document.' +PowerShellVersion = '5.0' +RequiredModules = @( + 'ATAPHtmlReport' +) +# RequiredAssemblies = @() +# ScriptsToProcess = @() +# TypesToProcess = @() +# FormatsToProcess = @() +# NestedModules = @() +FunctionsToExport = @( + 'Save-ATAPHtmlReport' + 'Invoke-ATAPReport' + 'Get-ATAPReport' + 'Get-AuditResource' + 'Test-AuditGroup' +) +CmdletsToExport = @() +VariablesToExport = '' +AliasesToExport = @( + 'shr' +) +# ModuleList = @() +# FileList = @() +PrivateData = @{ + PSData = @{ + Tags = @('reporting', 'auditing', 'benchmarks', 'fb-pro', 'html') + LicenseUri = 'https://github.com/fbprogmbh/Audit-Test-Automation/blob/master/LICENSE' + ProjectUri = 'https://github.com/fbprogmbh/Audit-Test-Automation' + # IconUri = '' + # ReleaseNotes = '' + + } # End of PSData hashtable + +} # End of PrivateData hashtable +# HelpInfoURI = '' +# DefaultCommandPrefix = 'ATAP' +} diff --git a/ATAPAuditor/ATAPAuditor.psm1 b/ATAPAuditor/ATAPAuditor.psm1 new file mode 100644 index 0000000..0a85d54 --- /dev/null +++ b/ATAPAuditor/ATAPAuditor.psm1 @@ -0,0 +1,931 @@ +using namespace Microsoft.PowerShell.Commands + +#region Initialization + +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +. "$RootPath\Helpers\HashHelper.ps1" + +$script:atapReportsPath = $env:ATAPReportPath +if (-not $script:atapReportsPath) { + $script:atapReportsPath = [Environment]::GetFolderPath('MyDocuments') | Join-Path -ChildPath 'ATAPReports' +} + +# for license status function. if called multiple times the cache will be used +$LicenseStatusCache = $null +#endregion + +#region Classes +class AuditTest { + [string] $Id + [string] $Task + [hashtable[]] $Constraints + [scriptblock] $Test +} + +enum AuditInfoStatus { + True + False + Warning + None + Error +} + +class AuditInfo { + [string] $Id + [string] $Task + [AuditInfoStatus] $Status + [string] $Message +} + +class ReportSection { + [string] $Title + [string] $Description + [AuditInfo[]] $AuditInfos + [ReportSection[]] $SubSections +} + +class Report { + [string] $Title + [string] $ModuleName + [string] $AuditorVersion + [hashtable] $HostInformation + [string[]] $BasedOn + [ReportSection[]] $Sections + [RSFullReport] $RSReport + [FoundationReport] $FoundationReport +} + + +################################################### +####### SYSTEM INFORMATION Classes ########## +################################################### +class SystemInformation { + [SoftwareInformation] $SoftwareInformation + [HardwareInformation] $HardwareInformation +} + +class SoftwareInformation { + [string] $Hostname + [string] $SystemUptime + [string] $OperatingSystem + [string] $BuildNumber + [string] $OSArchitecture + [string] $LicenseStatus + [string] $InstallationLanguage + [string] $DomainRole + [string] $KernelVersion +} + +class HardwareInformation { + [string] $SystemManufacturer + [string] $SystemSKU + [string] $SystemModel + [string] $SystemSerialnumber + [string] $BiosVersion + [string] $FreeDiskSpace + [string] $FreePhysicalMemory +} +### Begin Foundation Classes ### +class FoundationReport { + [ReportSection[]] $Sections +} +### End Foundation Classes + +# RiskScore Classes +enum RSEndResult { + Critical + High + Medium + Low + Unknown +} + +class RSFullReport { + [RSSeverityReport] $RSSeverityReport + [RSQuantityReport] $RSQuantityReport +} + +class RSSeverityReport { + [AuditInfo[]] $AuditInfos + [ResultTable[]] $ResultTable + [RSEndResult] $Endresult +} + +class RSQuantityReport { + +} + +class ResultTable { + [int] $Success + [int] $Failed +} + +#endregion + +#region helpers +function IsIn-FullLanguageMode { + try { + $languageMode = $ExecutionContext.SessionState.LanguageMode + if ($languageMode -eq "FullLanguage") { + return $true + } + } + catch { + return $false + } + # returns alternate language modes if not FullLanguage + return $languageMode +} + +function Start-ModuleTest { + $moduleList = @(Get-Module -ListAvailable).Name | Select-Object -Unique + $necessaryModules = @( + "Microsoft.PowerShell.LocalAccounts", + "Microsoft.PowerShell.Management", + "Microsoft.PowerShell.Security", + "Microsoft.PowerShell.Utility", + "TrustedPlatformModule", + "NetSecurity", + "CimCmdlets", + "SmbShare", + "Defender", + "DISM" + #Modules only necessary for specific server tests + #"IISAdministration", + #"SQLServer", + ) + $missingModules = @() + foreach ($module in $necessaryModules) { + if ($moduleList -notcontains $module) { + $missingModules += $module + } + } + if ($missingModules.Count -gt 0) { + Write-Warning "Missing module(s) found. Missing modules can lead to errors. Following modules are missing:" + for ($i = 0; $i -lt $missingModules.Count; $i++) { + Write-Warning $missingModules[$i] + } + Write-Warning "Check out this link on how to install modules: https://learn.microsoft.com/en-us/powershell/module/powershellget/install-module?view=powershellget-3.x" + } + +} + +function Get-LicenseStatus { + param( + $SkipLicenseCheck + ) + if ($LicenseStatusCache) { + return $LicenseStatusCache + } + + if ($SkipLicenseCheck -eq $true) { + $LicenseStatusCache = "License check has been skipped." + return $LicenseStatusCache + } + + Write-Host "Checking operating system activation status. This may take a while..." + $license = Get-CimInstance SoftwareLicensingProduct -Filter "Name like 'Windows%'" | Where-Object { $_.PartialProductKey } | Select-Object -First 1 + $LicenseStatusCache = switch ($license.LicenseStatus) { + "0" { "Unlicensed" } + "1" { "Licensed" } + "2" { "OOBGrace" } + "3" { "OOTGrace" } + "4" { "NonGenuineGrace" } + "5" { "Notification" } + "6" { "ExtendedGrace" } + } + return $LicenseStatusCache +} + +function IsIIS10Executable { + if ((Get-Module -ListAvailable IISAdministration) -eq $null) { + return $false + } + return $true +} + +function Test-ArrayEqual { + [OutputType([bool])] + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [AllowNull()] + [AllowEmptyCollection()] + [array] + $Array1, + + [Parameter(Mandatory = $true)] + [AllowNull()] + [AllowEmptyCollection()] + [array] + $Array2 + ) + + if ($null -eq $Array1) { + $Array1 = @() + } + + if ($null -eq $Array2) { + $Array2 = @() + } + + if ($Array1.Count -ne $Array2.Count) { + return $false + } + + foreach ($a in $Array1) { + if ($a -notin $Array2) { + return $false + } + } + return $true +} + +# Get domain role +# 0 {"Standalone Workstation"} +# 1 {"Member Workstation"} +# 2 {"Standalone Server"} +# 3 {"Member Server"} +# 4 {"Backup Domain Controller"} +# 5 {"Primary Domain Controller"} +function Get-DomainRole { + $domainRole = (Get-CimInstance -Class Win32_ComputerSystem).DomainRole + switch ($domainRole) { + 0 { $result = "Standalone Workstation" } + 1 { $result = "Member Workstation" } + 2 { $result = "Standalone Server" } + 3 { $result = "Member Server" } + 4 { $result = "Backup Domain Controller" } + 5 { $result = "Primary Domain Controller" } + } + return $result +} + +function checkReportNameWithOSSystem { + [CmdletBinding()] + param ( + [Parameter()] + [string] + $ReportName + ) + # helpers + function handleReportNameDiscrepancy { + param ( + [Parameter()] + [string] + $ReportName, + [Parameter()] + [string] + $OsName, + [Parameter()] + [bool] + $ShouldBeStandAlone = $False + ) + if ($ShouldBeStandAlone -eq $True) { + Write-Host "You chose the Reportname $ReportName but the operating system is domain-joined. Be aware that a different report type could affect the result." + } + else { + Write-Host "You chose the Reportname $ReportName but the operating system is $OsName. Be aware that a different report type could affect the result." + } + Write-Host "" + Write-Host "Choose one of the following options:" + Write-Host "[1] Continue [2] Exit Script" -ForegroundColor Yellow + $in = Read-Host + switch ($in) { + 1 { + Write-Host "You chose to continue" + return $ReportName + } + 2 { + Write-Host "You chose to exit the script" + return "Exit" + } + default { + Write-Host "Your input was invalid, call Save-ATAPHtmlReport again with your desired report" + return "Exit" + } + } + } + function returnSuitingReportName { + [CmdletBinding()] + param ( + [Parameter()] + [string] + $ReportName, + [Parameter()] + [string] + $OsName, + [Parameter()] + [string] + $OsType, + [Parameter()] + [bool] + $ShouldBeStandAlone = $False + ) + + ### + # similarity check + function isOsNameSimilarToType { + [CmdletBinding()] + param ( + [Parameter()] + [string] + $OsName, + [Parameter()] + [string] + $OsType + ) + if ($OsName -match $OsType) { + return $true + } + return $false + } + if (-not(isOsNameSimilarToType -OsName $osName -OsType $osType)) { + return handleReportNameDiscrepancy -ReportName $ReportName -OsName $osName + } + + ### + # should be standalone + if ($ShouldBeStandAlone -eq $True) { + function IsDomainedJoined { + if ((Get-CimInstance win32_computersystem).partofdomain) { + return $true + } + return $false + } + $isDomainJoined = IsDomainedJoined + if ($isDomainJoined -eq $True) { + return handleReportNameDiscrepancy -ReportName $ReportName -OsName $osName -ShouldBeStandAlone $True + } + } + return $ReportName + } + #helpers end + try { + $osName = (Get-ComputerInfo OsName).OsName + if ([string]::IsNullOrEmpty($osName)) { + return $ReportName # return initial ReportName and skip comparison + } + function Get-OsType { + switch ($ReportName) { + "Microsoft Windows Server 2025" { return "Microsoft Windows Server 2025" } + "Microsoft Windows Server 2022" { return "Microsoft Windows Server 2022" } + "Microsoft Windows Server 2019" { return "Microsoft Windows Server 2019" } + "Microsoft Windows Server 2016" { return "Microsoft Windows Server 2016" } + "Microsoft Windows Server 2012" { return "Microsoft Windows Server 2012" } + "Microsoft Windows 11" { return "Microsoft Windows 11" } + "Microsoft Windows 11 Stand-alone" { return "Microsoft Windows 11" } + "Microsoft Windows 10" { return "Microsoft Windows 10" } + "Microsoft Windows 10 Stand-alone" { return "Microsoft Windows 10" } + "Microsoft Windows 10 GDPR" { return "Microsoft Windows 10" } + "Microsoft Windows 10 BSI" { return "Microsoft Windows 10" } + "Microsoft Windows 7" { return "Microsoft Windows 7" } + } + } + $osType = Get-OsType + switch ($ReportName) { + "Microsoft Windows Server 2025" { + return returnSuitingReportName -ReportName $ReportName -OsName $osName -OsType $osType + } + "Microsoft Windows Server 2022" { + return returnSuitingReportName -ReportName $ReportName -OsName $osName -OsType $osType + } + "Microsoft Windows Server 2019" { + return returnSuitingReportName -ReportName $ReportName -OsName $osName -OsType $osType + } + "Microsoft Windows Server 2016" { + return returnSuitingReportName -ReportName $ReportName -OsName $osName -OsType $osType + } + "Microsoft Windows Server 2012" { + return returnSuitingReportName -ReportName $ReportName -OsName $osName -OsType $osType + } + "Microsoft Windows 11" { + return returnSuitingReportName -ReportName $ReportName -OsName $osName -OsType $osType + } + "Microsoft Windows 11 Stand-alone" { + return returnSuitingReportName -ReportName $ReportName -OsName $osName -OsType $osType -ShouldBeStandAlone $True + } + "Microsoft Windows 10" { + return returnSuitingReportName -ReportName $ReportName -OsName $osName -OsType $osType + } + "Microsoft Windows 10 Stand-alone" { + return returnSuitingReportName -ReportName $ReportName -OsName $osName -OsType $osType -ShouldBeStandAlone $True + } + "Microsoft Windows 10 GDPR" { + return returnSuitingReportName -ReportName $ReportName -OsName $osName -OsType $osType + } + "Microsoft Windows 10 BSI" { + return returnSuitingReportName -ReportName $ReportName -OsName $osName -OsType $osType + } + "Microsoft Windows 7" { + return returnSuitingReportName -ReportName $ReportName -OsName $osName -OsType $osType + } + } + return $ReportName + } + catch { + return $ReportName + } + +} + +### begin Foundation functions ### +function Get-FoundationReport { + [CmdletBinding()] + [OutputType([FoundationReport])] + + $Sections = @( + [ReportSection] @{ + Title = "Security Base Data" + SubSections = @( + [ReportSection] @{ + Title = 'Platform Security' + AuditInfos = Test-AuditGroup "SBD - Platform Security" + } + [ReportSection] @{ + Title = 'Windows Base Security' + AuditInfos = Test-AuditGroup "SBD - Windows Base Security" + } + [ReportSection] @{ + Title = 'PowerShell Security' + AuditInfos = Test-AuditGroup "SBD - PowerShell Security" + } + [ReportSection] @{ + Title = 'Connectivity Security' + AuditInfos = Test-AuditGroup "SBD - Connectivity Security" + } + [ReportSection] @{ + Title = 'Application Control' + AuditInfos = Test-AuditGroup "SBD - Application Control" + } + ) + } + ) + + return ([FoundationReport]@{ + Sections = $Sections + }) +} + + +# region for RiskScore functions +# function that calls all RiskScore-Subfunctions and generates the RSFullReport +function Get-RSFullReport { + [CmdletBinding()] + [OutputType([RSFullReport])] + + $severity = Get-RSSeverityReport + + + return ([RSFullReport]@{ + RSSeverityReport = $severity + }) +} +# function to generate RiskSeverityReport +function Get-RSSeverityReport { + [CmdletBinding()] + [OutputType([RSSeverityReport])] + + # Initialization + [AuditInfo[]]$tests = Test-AuditGroup "RSSeverityTests" + + # gather results of tests and save it in resultTable + $resultTable = [ResultTable]::new() + foreach ($test in $tests) { + if ($test.AuditInfoStatus -EQ "True") { + $resultTable.Success += 1 + } + if ($test.AuditInfostatus -ne "True") { + $resultTable.Failed += 1 + } + } + + return ([RSSeverityReport]@{ + AuditInfos = $tests + ResultTable = $resultTable + Endresult = Get-RSSeverityEndResult($resultTable) + }) +} + +# helper for EndResult of RiskScoreSeverity +function Get-RSSeverityEndResult { + [CmdletBinding()] + [OutputType([RSEndResult])] + + param ( + [Parameter(Mandatory = $true)] + [ResultTable[]] + $resultTable + ) + + $result = "Unknown" + + $f = $resultTable.Failed + if ($f -eq 0) { + $result = "Low" + } + if ($f -ge 1) { + $result = "Critical" + } + return $result +} + +#endregion + +<# +.SYNOPSIS + Tests a single AuditGroup. +.DESCRIPTION + This cmdlet tests a single AuditGroup from folder "AuditGroups". All tests are printed on the console. Can be combined to create own report. +.EXAMPLE + PS C:\> Test-AuditGroup "Google Chrome-CIS-2.0.0#RegistrySettings" + This runs tests defined in the AuditGroup file called 'Google Chrome-CIS-2.0.0#RegistrySettings'. +.PARAMETER GroupName + The name of the AuditGroup. +#> +function Test-AuditGroup { + [CmdletBinding()] + [OutputType([AuditInfo[]])] + param( + [Parameter(Mandatory = $true)] + [string] + $GroupName + ) + + #Windows OS + if ([System.Environment]::OSVersion.Platform -ne 'Unix') { + $tests = . "$RootPath\AuditGroups\$($GroupName).ps1" + } + #Linux OS + else { + $tests = . "$RootPath/AuditGroups/$($GroupName).ps1" + } + + + $i = 1 + foreach ($test in $tests) { + [int]$p = $i++ / $tests.Count * 100 + Write-Progress -Activity "Testing Report for '$GroupName'" -Status "Progress:" -PercentComplete $p + Write-Verbose "Testing $($test.Id)" + $message = "Test not implemented yet." + $status = [AuditInfoStatus]::None + #if audit test contains datatype "Constraints", proceed + if ($test.Constraints) { + $DomainRoleConstraint = $test.Constraints | Where-Object Property -EQ "DomainRole" + #get domain role of system + $currentRole = Get-DomainRole + #get domain roles, which are listed in AuditTest + $domainRoles = $DomainRoleConstraint.Values + if ($currentRole -notin $domainRoles) { + $roleValue = (Get-CimInstance -Class Win32_ComputerSystem).DomainRole + switch ($roleValue) { + 0 { + $message = 'Not applicable. This audit does not apply to Standalone Workstation.' + $status = [AuditInfoStatus]::None + } + 1 { + $message = 'Not applicable. This audit does not apply to Member Workstation.' + $status = [AuditInfoStatus]::None + } + 2 { + $message = 'Not applicable. This audit does not apply to Standalone Server.' + $status = [AuditInfoStatus]::None + } + 3 { + $message = 'Not applicable. This audit does not apply to Member Server.' + $status = [AuditInfoStatus]::None + } + 4 { + $message = 'Not applicable. This audit does not apply to Backup Domain Controller.' + $status = [AuditInfoStatus]::None + } + 5 { + $message = 'Not applicable. This audit does not apply to Primary Domain Controller.' + $status = [AuditInfoStatus]::None + } + } + Write-Output ([AuditInfo]@{ + Id = $test.Id + Task = $test.Task + Message = $message + Status = $status + }) + continue + } + } + + #Windows OS + if ([System.Environment]::OSVersion.Platform -ne 'Unix') { + $role = Get-Wmiobject -Class 'Win32_computersystem' -ComputerName $env:computername | Select-Object domainrole + if ($test.Task -match "(DC only)") { + if ($role.domainRole -ne 4 -and $role.domainRole -ne 5) { + $message = 'Not applicable. This audit does not apply to Member Server systems.' + $status = [AuditInfoStatus]::None + Write-Output ([AuditInfo]@{ + Id = $test.Id + Task = $test.Task + Message = $message + Status = $status + }) + continue + } + } + } + try { + $innerResult = & $test.Test + + if ($null -ne $innerResult) { + $message = $innerResult.Message + $status = [AuditInfoStatus]$innerResult.Status + } + } + catch { + Write-Error $_ + $message = "An error occured!" + $status = [AuditInfoStatus]::Error + } + + Write-Output ([AuditInfo]@{ + Id = $test.Id + Task = $test.Task + Message = $message + Status = $status + }) + } +} + +<# +.SYNOPSIS + Get an audit resource. +.DESCRIPTION + A resource provides abstration over an existing system resource. It is used by AuditTests. +.PARAMETER Name + The name of the resource. +.EXAMPLE + PS C:\> Get-AuditResource -Name "WindowsSecurityPolicy" + Gets the WindowsSecurityPolicy resource. +#> +function Get-AuditResource { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [string] + $Name + ) + #Windows OS + if ([System.Environment]::OSVersion.Platform -ne 'Unix') { + if ($null -eq $script:loadedResources) { + return & "$RootPath\Resources\$($Name).ps1" + } + if (-not $script:loadedResources.ContainsKey($Name)) { + $script:loadedResources[$Name] = (& "$RootPath\Resources\$($Name).ps1") + } + } + #Linuxs OS + else { + if ($null -eq $script:loadedResources) { + return & "$RootPath/Resources/$($Name).ps1" + } + if (-not $script:loadedResources.ContainsKey($Name)) { + $script:loadedResources[$Name] = (& "$RootPath/Resources/$($Name).ps1") + } + } + return $script:loadedResources[$Name] +} + +<# +.SYNOPSIS + Get all reports. +.DESCRIPTION + Find the reports installed on the system. +.PARAMETER ReportName + The name of the report. +.EXAMPLE + PS C:\> Get-ATAPReport + Gets all reports. +#> +function Get-ATAPReport { + [CmdletBinding()] + param ( + [Parameter()] + [string] + $ReportName = "*" + ) + #Windows OS + if ([System.Environment]::OSVersion.Platform -ne 'Unix') { + return Get-ChildItem "$RootPath\Reports\$ReportName.ps1" | Select-Object -Property BaseName + } + #Linux OS + return Get-ChildItem "$RootPath/Reports/$ReportName.ps1" | Select-Object -Property BaseName +} + +<# +.SYNOPSIS + Invokes an ATAPReport +.DESCRIPTION + Long description +.EXAMPLE + PS C:\> ATAPReport -ReportName "Google Chrome" + This runs the report and outputs the logical report data. +.PARAMETER ReportName + The name of the report. +.OUTPUTS + Logical report data. +#> +function Invoke-ATAPReport { + [CmdletBinding()] + param ( + [Alias('RN')] + [Parameter(Mandatory = $true)] + [string] + $ReportName + ) + + $script:loadedResources = @{} + # Load the module manifest + + #Windows OS + try { + if ([System.Environment]::OSVersion.Platform -ne 'Unix') { + $moduleInfo = Import-PowerShellDataFile -Path "$RootPath\ATAPAuditor.psd1" + [string]$ReportName = checkReportNameWithOSSystem -ReportName $ReportName + try { + if ($ReportName -eq "Exit") { + throw + } + } + catch { + Write-Host "Script halted: Exiting..." + break + } + [Report]$report = (& "$RootPath\Reports\$ReportName.ps1") + $report.RSReport = Get-RSFullReport + $report.FoundationReport = Get-FoundationReport + } + #Linux OS + else { + $moduleInfo = Import-PowerShellDataFile -Path "$RootPath/ATAPAuditor.psd1" + [Report]$report = (& "$RootPath/Reports/$ReportName.ps1") + } + } + catch [System.Management.Automation.CommandNotFoundException] { + Write-Host "Either your input for -Reportname is faulty or the report does not resolve due to a bug. Please report this bug with the following errormessage: + 1. ErrorException: $_ + 2. PositionMessage: $($_.InvocationInfo.PositionMessage) + 3. ReportName: $ReportName" + break + } + $report.AuditorVersion = $moduleInfo.ModuleVersion + return $report +} + +<# +.SYNOPSIS + The Audit Test Automation Package creates transparents reports about hardening compliance status +.DESCRIPTION + The Audit Test Automation Package gives you the ability to get an overview about the compliance status of several systems. + You can easily create HTML-reports and have a transparent overview over compliance and non-compliance of explicit setttings + and configurations in comparison to industry standards and hardening guides. +.EXAMPLE + PS C:\> Save-ATAPHtmlReport -ReportName "Microsoft Windows 10 Complete" -RiskScore -Path C:\Temp\report.html + This runs the 'Microsoft Windows 10 Complete' report, adding RiskScore to it and stores the resulting html file under C:\Temp using the file name report.html +.EXAMPLE + PS C:\> Save-ATAPHtmlReport -ReportName "Microsoft Windows 10 BSI" -RiskScore -Path C:\Temp + This runs the 'Microsoft Windows 10 BSI' report, adding RiskScore to it and stores the resulting html file under C:\Temp using the standard naming convention for file names .html +.EXAMPLE + PS C:\> Save-ATAPHtmlReport -ReportName "Microsoft Windows Server 2022" -Path C:\Temp + This runs the 'Microsoft Windows Server 2022' report, without adding RiskScore to it and stores the resulting html file under C:\Temp using the standard naming convention for file names .html +.EXAMPLE + PS C:\> Save-ATAPHtmlReport -ReportName "Google Chrome" + This runs the 'Google Chrome' report and stores the resulting html file (by default) under ~\Documents\ATAPReports +.EXAMPLE + PS C:\> Save-ATAPHtmlReport -ReportName "Ubuntu 20.04" + This runs the 'Ubuntu 20.04' report and stores the resulting html file (by default) under ~\Documents\ATAPReports +.PARAMETER ReportName + Determine, which OS shall be tested. +.PARAMETER Path + The path where the result html document should be stored. +.PARAMETER RiskScore + Add a RiskScore-Matrix to report (works only on Windows OS) +.PARAMETER MITRE + Add a MITRE ATT&CK headmap to report (works only on Windows OS) +.PARAMETER Force + If the parent directory doesn't exist it will be created. +.OUTPUTS + None. +#> +function Save-ATAPHtmlReport { + [CmdletBinding()] + param( + [Alias('RN')] + [Parameter(Mandatory = $true)] + [string] + $ReportName, + + [Parameter(Mandatory = $false)] + [string] + $Path = ($script:atapReportsPath | Join-Path -ChildPath "$($ReportName)_$(Get-Date -UFormat %Y%m%d_%H%M%S).html"), + + [Parameter(Mandatory = $false)] + [switch] + $RiskScore, + + [Parameter(Mandatory = $false)] + [switch] + $SkipLicenseCheck, + # [Parameter(Mandatory = $false)] + # [switch] + # $MITRE, + + [Parameter()] + [switch] + $Force + ) + + if ([Environment]::Is64BitProcess -eq $false) { + Write-Host "Please use 64-bit version of PowerShell in order to use AuditTAP. Closing..." -ForegroundColor red + return; + } + + if (($languagemode = IsIn-FullLanguageMode) -ne $true) { + if ($languagemode -eq $false) { + Write-Host "The current language mode could not be determined. Ensure that AuditTAP is run in `"FullLanguage`" mode. For further information, contact your administrator. Closing..." -ForegroundColor red + } + else { + Write-Host "The current language mode is `"$languagemode`". Ensure that AuditTAP is run in `"FullLanguage`" mode. For further information, contact your administrator. Closing..." -ForegroundColor red + } + return + } + + $parent = $path + if ($Path -match ".html") { + $parent = Split-Path -Path $Path + } + + #if input path is not default one + if ($parent -ne $script:atapReportsPath) { + $pathCheck = Test-Path -Path $parent -PathType Container + #if path doesn't exist + if ($pathCheck -eq $False) { + if (-not [string]::IsNullOrEmpty($parent) -and -not (Test-Path $parent)) { + New-Item -ItemType Directory -Path $parent -Force | Out-Null + Write-Warning "Could not find Path. Path will be created: $parent" + } + else { + Write-Warning "Could not find Path. Report will be created inside default path: $($script:atapReportsPath)" + $Path = $($script:atapReportsPath) + } + } + } + Write-Verbose "OS-Check" + $isUnix = [System.Environment]::OSVersion.Platform -eq 'Unix' + if ($isUnix) { + [SystemInformation] $SystemInformation = (& "$PSScriptRoot\Helpers\ReportUnixOS.ps1") + } + else { + [SystemInformation] $SystemInformation = (& "$PSScriptRoot\Helpers\ReportWindowsOS.ps1") + Start-ModuleTest + if ($ReportName -eq "Microsoft IIS10") { + $isIIS10Executable = IsIIS10Executable + if ($isIIS10Executable -eq $false) { + Write-Warning "IIS10 Report not executable! IISAdministration module not available. Please install this module and try again. Exiting..." + return; + } + } + Write-Verbose "PS-Check" + $psVersion = $PSVersionTable.PSVersion + #PowerShell Major version not 5.* + if (($psVersion.Major -ne 5)) { + Write-Warning "ATAPAuditor is only compatible with PowerShell Version 5.1. Your version is $psVersion. Please open a PowerShell Version 5.1 session to continue!" + return; + } + #PowerShell version not 5.1 + if (($psVersion.Major -eq 5) -and ($psVersion.Minor -eq 0)) { + Write-Warning "ATAPAuditor is only compatible with PowerShell Version 5.1. Your version is $psVersion. You need to upgrade to a higher Windows version!" + return; + } + } + + $report = Invoke-ATAPReport -ReportName $ReportName + #hashes for each recommendation + if (!$isUnix) { + $SystemInformation.SoftwareInformation.LicenseStatus = Get-LicenseStatus $SkipLicenseCheck + } + $hashtable_sha256 = GenerateHashTable $report + + $report | Get-ATAPHtmlReport -Path $Path -RiskScore:$RiskScore -MITRE:$MITRE -hashtable_sha256:$hashtable_sha256 -LicenseStatus:$LicenseStatus -SystemInformation:$SystemInformation +} + +New-Alias -Name 'shr' -Value Save-ATAPHtmlReport + +$completer = { + param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) + + Get-ChildItem "$RootPath\Reports\*.ps1" ` + | Select-Object -ExpandProperty BaseName ` + | ForEach-Object { "`"$_`"" } ` + | Where-Object { $_ -like "*$wordToComplete*" } +}.GetNewClosure() + +Register-ArgumentCompleter -CommandName Save-ATAPHtmlReport -ParameterName ReportName -ScriptBlock $completer +Register-ArgumentCompleter -CommandName shr -ParameterName ReportName -ScriptBlock $completer diff --git a/ATAPAuditor/AuditGroups/CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings.ps1 new file mode 100644 index 0000000..ac75b3a --- /dev/null +++ b/ATAPAuditor/AuditGroups/CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings.ps1 @@ -0,0 +1,1852 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$listOfWeakCipherSuites = getListOfWeakCipherSuites +$listOfInsecureCipherSuites = getListOfInsecureCipherSuites +[AuditTest] @{ + Id = "1.1 A" + Task = "Disable SSLv2 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1 B" + Task = "Disable SSLv2 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1 C" + Task = "Disable SSLv2 Protocol (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1 D" + Task = "Disable SSLv2 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2 A" + Task = "Disable SSLv3 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + $OS = Get-CimInstance Win32_OperatingSystem + if($OS.Caption -match "Server 2012 R2"){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2 B" + Task = "Disable SSLv3 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + $OS = Get-CimInstance Win32_OperatingSystem + if($OS.Caption -match "Server 2012 R2"){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2 C" + Task = "Disable SSLv3 Protocol (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + $OS = Get-CimInstance Win32_OperatingSystem + if($OS.Caption -match "Server 2012 R2"){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2 D" + Task = "Disable SSLv3 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + $OS = Get-CimInstance Win32_OperatingSystem + if($OS.Caption -match "Server 2012 R2"){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3 A" + Task = "Disable TLS1.0 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3 B" + Task = "Disable TLS1.0 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3 C" + Task = "Disable TLS1.0 Protocol (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3 D" + Task = "Disable TLS1.0 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.4 A" + Task = "Disable TLS1.1 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.4 B" + Task = "Disable TLS1.1 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.4 C" + Task = "Disable TLS1.1 Protocol (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.4 D" + Task = "Disable TLS1.1 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.5 A" + Task = "Enable TLS1.2 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -eq 4294967295) { + return @{ + Message = "The current registry value is '$regValue', which is no longer supported by Microsoft. For more information, please refer to this link:
"` + +''` + +'Learn.microsoft.com - TLS, DTLS, and SSL protocol version settings' + Status = "False" + } + } + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.5 B" + Task = "Enable TLS1.2 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.5 C" + Task = "Enable TLS1.2 Protocol (Client)" + Test = { + $OS = Get-CimInstance Win32_OperatingSystem | Select-Object Caption + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -eq 4294967295) { + return @{ + Message = "The current registry value is '$regValue', which is no longer supported by Microsoft. For more information, please refer to this link:
"` + +'
'` + +'Learn.microsoft.com - TLS, DTLS, and SSL protocol version settings' + Status = "False" + } + } + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + if($OS -match "Server 2022" -or $OS -match "Windows 11"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + if($OS -match "Server 2022" -or $OS -match "Windows 11"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.5 D" + Task = "Enable TLS1.2 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.6 A" + Task = "Enable TLS1.3 Protocol (Server)" + Test = { + try{ + $OS = (Get-CimInstance Win32_OperatingSystem).Caption + if($OS -notmatch "Server 2022" -and $OS -notmatch "Windows 11"){ + return @{ + Message = "OS currently not supported. For more information check out this link: TLS protocol version support" + Status = "None" + } + } + } + catch{ + return @{ + Message = "Test not successful. Cmdlet not found 'Get-CimInstance'. " + Status = "None" + } + } + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "PowerShell cmdlet not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + if($OS -match "Server 2022" -or $OS -match "Windows 11"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.6 B" + Task = "Enable TLS1.3 Protocol (Server DisabledByDefault)" + Test = { + try{ + $OS = (Get-CimInstance Win32_OperatingSystem).Caption + if($OS -notmatch "Server 2022" -and $OS -notmatch "Windows 11"){ + return @{ + Message = "OS currently not supported. For more information check out this link: TLS protocol version support" + Status = "None" + } + } + } + catch{ + return @{ + Message = "Test not successful. Cmdlet not found 'Get-CimInstance'. " + Status = "None" + } + } + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "PowerShell cmdlet not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + if($OS -match "Server 2022" -or $OS -match "Windows 11"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.6 C" + Task = "Enable TLS1.3 Protocol (Client)" + Test = { + try{ + $OS = (Get-CimInstance Win32_OperatingSystem).Caption + if($OS -notmatch "Server 2022" -and $OS -notmatch "Windows 11"){ + return @{ + Message = "OS currently not supported. For more information check out this link: TLS protocol version support" + Status = "None" + } + } + } + catch{ + return @{ + Message = "Test not successful. Cmdlet not found 'Get-CimInstance'. " + Status = "None" + } + } + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "PowerShell cmdlet not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + if($OS -match "Server 2022" -or $OS -match "Windows 11"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.6 D" + Task = "Enable TLS1.3 Protocol (Client DisabledByDefault)" + Test = { + try{ + $OS = (Get-CimInstance Win32_OperatingSystem).Caption + if($OS -notmatch "Server 2022" -and $OS -notmatch "Windows 11"){ + return @{ + Message = "OS currently not supported. For more information check out this link: TLS protocol version support" + Status = "None" + } + } + } + catch{ + return @{ + Message = "Test not successful. Cmdlet not found 'Get-CimInstance'. " + Status = "None" + } + } + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "PowerShell cmdlet not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + if($OS -match "Server 2022" -or $OS -match "Windows 11"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.1" + Task = "Disable NULL Cipher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\NULL" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.2" + Task = "Disable DES Cipher Suite" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\DES 56/56" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.4 A" + Task = "Disable RC4 Cipher Suite - 40/128" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.4 B" + Task = "Disable RC4 Cipher Suite - 56/128" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.4 C" + Task = "Disable RC4 Cipher Suite - 64/128" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 64/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.4 D" + Task = "Disable RC4 Cipher Suite - 128/128" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.5" + Task = "Disable AES 128/128 Cipher Suite" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\AES 128/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.6" + Task = "Disable Triple DES Cipher Suite" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\Triple DES 168" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.7" + Task = "Enable AES 256/256 Cipher Suite" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\AES 256/256" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -eq 4294967295) { + return @{ + Message = "The current registry value is '$regValue', which is no longer supported by Microsoft. For more information, please refer to this link:
"` + +''` + +'Learn.microsoft.com - TLS, DTLS, and SSL protocol version settings' + Status = "False" + } + } + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.1" + Task = "Configure Cipher Suite Ordering" + Test = { + #check if correct type + $typeTable = @{ + "String" = "String Value" + "Byte" = "Byte Value" + "Int32" = "DWORD (32-bit) Value" + "Int64" = "QWORD (64-bit) Value" + "String[]" = "Multi-String Value" + } + #Default status + $status = "Error" + + #Output + $verbInsecure = "rules have" + $verbWeak = "rules have" + + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002" ` + -Name "Functions" + $reference = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" + $res = $regValue.Functions.GetType().Name + + + $currentType = $typeTable[$res] + if ($res -ne [String]) { + return @{ + Message = "Wrong Registry type! Registry type is '$currentType'. Expected: 'String Value'" + Status = "False" + } + } + + #check if insecure or weak cipher is inside value + $regValues = $regValue.Split(',') + $regValues = $regValues -replace ' ', '' + $weakRulesFound = @() + $insecureRulesFound = @() + foreach($element in $regValues){ + if($listOfWeakCipherSuites.Contains($element)){ + $weakRulesFound += $element + } + if($listOfInsecureCipherSuites.Contains($element)){ + $insecureRulesFound += $element + } + } + if($insecureRulesFound.Count -eq 1){$verbInsecure = "rule has"} + if($weakRulesFound.Count -eq 1){$verbWeak = "rule has"} + $insecureMessage = "$($insecureRulesFound.Count) insecure $($verbInsecure) been found! List of insecure rules:
" + $weakMessage = "$($weakRulesFound.Count) weak $($verbWeak) been found! List of weak rules:
" + + #Preparing message + foreach($member in $weakRulesFound){ + $status = "Warning" + $weakMessage += "$($member)
" + } + foreach($member in $insecureRulesFound){ + $status = "False" + $insecureMessage += "$($member)
" + } + #Combine or shorten message + if($insecureRulesFound.Count -gt 0 -or $weakRulesFound.Count -gt 0){ + $message = "" + if($weakRulesFound.Count -eq 0){ $weakMessage = "" } + if($insecureRulesFound.Count -eq 0){ $insecureMessage = "" } + + $message = $insecureMessage + $weakMessage + return @{ + Message = $message + Status = $status + } + } + + if ($regValue -ne $reference) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002" ` + -Name "Functions" + $reference = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" + $res = $regValue.Functions.GetType().Name + + $currentType = $typeTable[$res] + if ($res -ne [String[]]) { + return @{ + Message = "Wrong Registry type! Registry type is '$currentType'. Expected: 'Multi-String Value'" + Status = "False" + } + } + + #check if insecure or weak cipher is inside value + $regValues = $regValue -replace ' ', '' + $weakRulesFound = @() + $insecureRulesFound = @() + foreach($element in $regValues){ + if($listOfWeakCipherSuites.Contains($element)){ + $weakRulesFound += $element + } + if($listOfInsecureCipherSuites.Contains($element)){ + $insecureRulesFound += $element + } + } + if($insecureRulesFound.Count -eq 1){$verbInsecure = "rule has"} + if($weakRulesFound.Count -eq 1){$verbWeak = "rule has"} + $insecureMessage = "$($insecureRulesFound.Count) insecure $($verbInsecure) been found! List of insecure rules:
" + $weakMessage = "$($weakRulesFound.Count) weak $($verbWeak) been found! List of weak rules:
" + + #Preparing message + foreach($member in $weakRulesFound){ + $status = "Warning" + $weakMessage += "$($member)
" + } + foreach($member in $insecureRulesFound){ + $status = "False" + $insecureMessage += "$($member)
" + } + #Combine or shorten message + if($insecureRulesFound.Count -gt 0 -or $weakRulesFound.Count -gt 0){ + $message = "" + if($weakRulesFound.Count -eq 0){ $weakMessage = "" } + if($insecureRulesFound.Count -eq 0){ $insecureMessage = "" } + + $message = $insecureMessage + $weakMessage + return @{ + Message = $message + Status = $status + } + } + + if ($regValue -ne $reference) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.1" + Task = "Disable SHA-1 hash" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Hashes\SHA" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.2" + Task = "Disable MD5 hash" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Hashes\MD5" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1 A" + Task = "Enable .Net Strong Crypto v2.0.50727 SystemDefaultTlsVersions 32 Bit on 64 Bit System" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v2.0.50727" ` + -Name "SystemDefaultTlsVersions" ` + | Select-Object -ExpandProperty "SystemDefaultTlsVersions" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1 B" + Task = "Enable .Net Strong Crypto v2.0.50727 SchUseStrongCrypto 32 Bit on 64 Bit System" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v2.0.50727" ` + -Name "SchUseStrongCrypto" ` + | Select-Object -ExpandProperty "SchUseStrongCrypto" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1 C" + Task = "Enable .Net Strong Crypto v2.0.50727 SystemDefaultTlsVersions" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727" ` + -Name "SystemDefaultTlsVersions" ` + | Select-Object -ExpandProperty "SystemDefaultTlsVersions" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1 D" + Task = "Enable .Net Strong Crypto v2.0.50727 SchUseStrongCrypto" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727" ` + -Name "SchUseStrongCrypto" ` + | Select-Object -ExpandProperty "SchUseStrongCrypto" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2 A" + Task = "Enable .Net Strong Crypto v4.0.30319 SystemDefaultTlsVersions 32 Bit on 64 Bit System" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319" ` + -Name "SystemDefaultTlsVersions" ` + | Select-Object -ExpandProperty "SystemDefaultTlsVersions" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2 B" + Task = "Enable .Net Strong Crypto v4.0.30319 SchUseStrongCrypto 32 Bit on 64 Bit System" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319" ` + -Name "SchUseStrongCrypto" ` + | Select-Object -ExpandProperty "SchUseStrongCrypto" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2 C" + Task = "Enable .Net Strong Crypto v4.0.30319 SystemDefaultTlsVersions" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" ` + -Name "SystemDefaultTlsVersions" ` + | Select-Object -ExpandProperty "SystemDefaultTlsVersions" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2 D" + Task = "Enable .Net Strong Crypto v4.0.30319 SchUseStrongCrypto" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" ` + -Name "SchUseStrongCrypto" ` + | Select-Object -ExpandProperty "SchUseStrongCrypto" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} \ No newline at end of file diff --git a/ATAPAuditor/AuditGroups/Debian Linux 11-CIS-1.0.0.ps1 b/ATAPAuditor/AuditGroups/Debian Linux 11-CIS-1.0.0.ps1 new file mode 100644 index 0000000..93cecca --- /dev/null +++ b/ATAPAuditor/AuditGroups/Debian Linux 11-CIS-1.0.0.ps1 @@ -0,0 +1,5295 @@ +[AuditTest] @{ + Id = "1.1.1.1" + Task = "Ensure mounting of cramfs filesystems is disabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.1.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.1.2" + Task = "Ensure mounting of squashfs filesystems is disabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.2.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.1.3" + Task = "Ensure mounting of udf filesystems is disabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.3.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.2.1" + Task = "Ensure /tmp is a separate partition" + Test = { + $result = findmnt --kernel /tmp + if ($result -match "/tmp") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.2.2" + Task = "Ensure nodev option set on /tmp partition" + Test = { + $result = findmnt --kernel /tmp | grep nodev + if ($result -match "nodev") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.2.3" + Task = "Ensure noexec option set on /tmp partition" + Test = { + $result = findmnt --kernel /tmp | grep noexec + if ($result -match "noexec") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.2.4" + Task = "Ensure nosuid option set on /tmp partition" + Test = { + $result = findmnt --kernel /tmp | grep nosuid + if ($result -match "nosuid") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.3.1" + Task = "Ensure separate partition exists for /var" + Test = { + $result = findmnt --kernel /var + if ($result -match "/var") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.3.2" + Task = "Ensure nodev option set on /var partition" + Test = { + $result = findmnt --kernel /var + if ($result -match "nodev") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.3.3" + Task = "Ensure nosuid option set on /var partition" + Test = { + $result = findmnt --kernel /var + if ($result -match "nosuid") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.4.1" + Task = "Ensure separate partition exists for /var/tmp" + Test = { + $result = findmnt --kernel /var/tmp + if ($result -match "/var/tmp") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.4.2" + Task = "Ensure noexec option set on /var/tmp partition" + Test = { + $result = findmnt --kernel /var/tmp + + # if no separate partition, at least the flag is set + if ($result -eq $null) { + $result = findmnt --kernel /var + } + + if ($result -match "noexec") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.4.3" + Task = "Ensure nosuid option set on /var/tmp partition" + Test = { + $result = findmnt --kernel /var/tmp + + # if no separate partition, at least the flag is set + if ($result -eq $null) { + $result = findmnt --kernel /var + } + + if ($result -match "nosuid") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.4.4" + Task = "Ensure nodev option set on /var/tmp partition" + Test = { + $result = findmnt --kernel /var/tmp + + # if no separate partition, at least the flag is set + if ($result -eq $null) { + $result = findmnt --kernel /var + } + + if ($result -match "nodev") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.5.1" + Task = "Ensure separate partition exists for /var/log" + Test = { + $result = findmnt --kernel /var/log + + # if no separate partition, at least the flag is set + if ($result -eq $null) { + $result = findmnt --kernel /var + } + + if ($result -match "/var/log") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.5.2" + Task = "Ensure nodev option set on /var/log partition" + Test = { + $result = findmnt --kernel /var/log + + # if no separate partition, at least the flag is set + if ($result -eq $null) { + $result = findmnt --kernel /var + } + + if ($result -match "nodev") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.5.3" + Task = "Ensure noexec option set on /var/log partition" + Test = { + $result = findmnt --kernel /var/log + + # if no separate partition, at least the flag is set + if ($result -eq $null) { + $result = findmnt --kernel /var + } + + if ($result -match "noexec") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.5.4" + Task = "Ensure nosuid option set on /var/log partition" + Test = { + $result = findmnt --kernel /var/log + + # if no separate partition, at least the flag is set + if ($result -eq $null) { + $result = findmnt --kernel /var + } + + if ($result -match "nosuid") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.6.1" + Task = "Ensure separate partition exists for /var/log/audit" + Test = { + $result = findmnt --kernel /var/log/audit + if ($result -match "/var/log/audit") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.6.2" + Task = "Ensure noexec option set on /var/log/audit partition" + Test = { + $result = findmnt --kernel /var/log/audit + + # if no separate partition, at least the flag is set + if ($result -eq $null) { + $result = findmnt --kernel /var + } + + if ($result -match "noexec") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.6.3" + Task = "Ensure nodev option set on /var/log/audit partition" + Test = { + $result = findmnt --kernel /var/log/audit + + # if no separate partition, at least the flag is set + if ($result -eq $null) { + $result = findmnt --kernel /var + } + + if ($result -match "nodev") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.6.4" + Task = "Ensure nosuid option set on /var/log/audit partition" + Test = { + $result = findmnt --kernel /var/log/audit + + # if no separate partition, at least the flag is set + if ($result -eq $null) { + $result = findmnt --kernel /var + } + + if ($result -match "nosuid") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.7.1" + Task = "Ensure separate partition exists for /home" + Test = { + $result = findmnt --kernel /home + if ($result -match "/home") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.7.2" + Task = "Ensure nodev option set on /home partition" + Test = { + $result = findmnt --kernel /home + if ($result -match "nodev") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.7.3" + Task = "Ensure nosuid option set on /home partition" + Test = { + $result = findmnt --kernel /home + if ($result -match "nosuid") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.8.1" + Task = "Ensure nodev option set on /dev/shm partition" + Test = { + $result = findmnt --kernel /dev/shm | grep nodev + if ($result -match "nodev") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.8.2" + Task = "Ensure noexec option set on /dev/shm partition" + Test = { + $result = findmnt --kernel /dev/shm | grep noexec + if ($result -match "noexec") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.8.3" + Task = "Ensure nosuid option set on /dev/shm partition" + Test = { + $result = findmnt --kernel /dev/shm | grep nosuid + if ($result -match "nosuid") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.9" + Task = "Disable Automounting" + Test = { + $result1 = systemctl is-enabled autofs + $status = $? + # error occurs when autofs is not installed, that is compliant, too + if ($status -match "False") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + if ($result1 -match "Failed" -and ($result1 -match "Failed" -or $result1 -match "disabled")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.10" + Task = "Disable USB Storage" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.10.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "Ensure package manager repositories are configured" + Test = { + $result = apt-cache policy + if ($result -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "Ensure GPG keys are configured" + Test = { + $result = apt-key list + if ($result -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.3.1" + Task = "Ensure AIDE is installed" + Test = { + $result = dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' aide aide-common + if ($result -match "install ok installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.3.2" + Task = "Ensure filesystem integrity is regularly checked" + Test = { + $result = grep -Prs '^([^#\n\r]+\h+)?(\/usr\/s?bin\/|^\h*)aide(\.wrapper)?\h+(--check|([^#\n\r]+\h+)?\$AIDEARGS)\b' /etc/cron.* /etc/crontab /var/spool/cron/ + if ($result -match "install ok installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.4.1" + Task = "Ensure bootloader password is set" + Test = { + $result1 = grep "^set superusers" /boot/grub/grub.cfg + $result2 = grep "^password" /boot/grub/grub.cfg + + if ($result1 -match "set superusers=" -and $result2 -match "password_pbkdf2") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.4.2" + Task = "Ensure permissions on bootloader config are configured" + Test = { + $test1 = stat /boot/grub/grub.cfg | grep 0400 + if ($test1 -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.4.3" + Task = "Ensure authentication required for single user mode" + Test = { + $command = @' +grep -Eq '^root:\$(y|[0-9])' /etc/shadow || echo 'root is locked' +'@ + $result = bash -c $command + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.5.1" + Task = "Ensure address space layout randomization (ASLR) is enabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.5.1.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.5.2" + Task = "Ensure prelink is not installed" + Test = { + $result = dpkg -l | grep -o prelink + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.5.3" + Task = "Ensure Automatic Error Reporting is not enabled" + Test = { + $command = "dpkg-query -s apport > /dev/null 2>&1 && grep -Psi --'^\h*enabled\h*=\h*[^0]\b' /etc/default/apport" + $result1 = bash -c $command + $result2 = systemctl is-active apport.service | grep '^active' + if ($result1 -eq $null -and $result2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.5.4" + Task = "Ensure core dumps are restricted" + Test = { + try { + $result1 = grep -Es '^(\*|\s).*hard.*core.*(\s+#.*)?$' /etc/security/limits.conf /etc/security/limits.d/* + $result2 = sysctl fs.suid_dumpable + $result3 = grep "fs.suid_dumpable" /etc/sysctl.conf /etc/sysctl.d/* + try { + $result4 = systemctl is-enabled coredump.service + $message = "Compliant" + if ($result4 -match "enabled" -or $result4 -match "masked" -or $result4 -match "disabled") { + $message = "systemd-coredump is installed" + } + } + catch { + $message = "systemd-coredump not installed" + } + if ($result1 -match ".*\s*hard\s*core\s*0{1}?\s*" -and $result2 -match "fs.suid_dumpable = 0" -and $result3 -match "fs.suid_dumpable = 0") { + return @{ + Message = $message + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "1.6.1.1" + Task = "Ensure AppArmor is installed" + Test = { + $result = dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' apparmor apparmor-utils + if ($result -match "apparmor\s+install ok installed\s+installed" -and $result -match "apparmor-utils\s+install ok installed\s+installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.6.1.2" + Task = "Ensure AppArmor is enabled in the bootloader configuration" + Test = { + $result1 = grep "^\s*linux" /boot/grub/grub.cfg | grep -v "apparmor=1" + $result2 = grep "^\s*linux" /boot/grub/grub.cfg | grep -v "security=apparmor" + if ($result1 -eq $null -and $result2 -eq $null ) { + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.6.1.3" + Task = "Ensure all AppArmor Profiles are in enforce or complain mode" + Test = { + $profileMode1 = apparmor_status | grep profiles | sed '1!d' | cut -d ' ' -f 1 + $profileMode2 = apparmor_status | grep profiles | sed '2!d' | cut -d ' ' -f 1 + $profileMode3 = apparmor_status | grep profiles | sed '3!d' | cut -d ' ' -f 1 + $result = expr $profileMode3 + $profileMode2 + + $unconfinedProcesses = apparmor_status | grep processes | sed '4!d' | cut -d ' ' -f 1 + + if ($result -eq $profileMode1 -and $unconfinedProcesses -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.6.1.4" + Task = "Ensure all AppArmor Profiles are enforcing" + Test = { + $profileMode1 = apparmor_status | grep profiles | sed '1!d' | cut -d ' ' -f 1 + $profileMode2 = apparmor_status | grep profiles | sed '2!d' | cut -d ' ' -f 1 + + $unconfinedProcesses = apparmor_status | grep processes | sed '4!d' | cut -d ' ' -f 1 + + if ($profileMode1 -eq $profileMode2 -and $unconfinedProcesses -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.7.1" + Task = "Ensure message of the day is configured properly" + Test = { + $output = grep -Eis "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/motd + + if ($output -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.7.2" + Task = "Ensure local login warning banner is configured properly" + Test = { + $output1 = cat /etc/issue + $output2 = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue + + if ($output1 -ne $null -and $output2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.7.3" + Task = "Ensure remote login warning banner is configured properly" + Test = { + $output1 = cat /etc/issue.net + $output2 = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue.net + + if ($output1 -ne $null -and $output2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.7.4" + Task = "Ensure permissions on /etc/motd are configured" + Test = { + if (Test-Path /etc/motd) { + $test1 = stat /etc/motd | grep 0644 + if ($test1 -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + else { + return @{ + Message = "motd not present" + Status = "None" + } + } + } +} +[AuditTest] @{ + Id = "1.7.5" + Task = "Ensure permissions on /etc/issue are configured" + Test = { + $output = stat -L /etc/issue | grep "Access:\s*(0644/-rw-r--r--)\s*Uid:\s*(\s*0/\s*root)\s*Gid:\s*(\s*0/\s*root)" + + if ($output -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.1" + Task = "Ensure GNOME Display Manager is removed" + Test = { + $test = dpkg -l | grep "^ii" | grep -q "gdm3" + $output = $? + if ($output -match "False") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.2" + Task = "Ensure GDM login banner is configured" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.2.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.3" + Task = "Ensure GDM disable-user-list option is enabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.3.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.4" + Task = "Ensure GDM screen locks when the user is idle" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.4.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.5" + Task = "Ensure GDM screen locks cannot be overridden" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.5.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.6" + Task = "Ensure GDM automatic mounting of removable media is disabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.6.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.7" + Task = "Ensure GDM disabling automatic mounting of removable media is not overridden" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.7.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.8" + Task = "Ensure GDM autorun-never is enabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.8.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.9" + Task = "Ensure GDM autorun-never is not overridden" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.9.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.10" + Task = "Ensure XDCMP is not enabled" + Test = { + $output = grep -Eis '^\s*Enable\s*=\s*true' /etc/gdm3/custom.conf + if ($output -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.9" + Task = "Ensure updates, patches, and additional security software are installed" + Test = { + $output = apt -s upgrade + $output = $? + if ($output -match "True") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.1.1" + Task = "Ensure a single time synchronization daemon is in use" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-2.1.1.1.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.2.1" + Task = "Ensure chrony is configured with authorized timeserver" + Test = { + $output = apt -s upgrade + $output = $? + if ($output -match "True") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.2.2" + Task = "Ensure chrony is running as user _chrony" + Test = { + $testchr = dpkg-query -s chrony + $statuschr = $? + if ($statuschr -match "True") { + $result = ps -ef | awk '(/[c]hronyd/ && $1!="_chrony") { print $1 }' + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "chrony not installed" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "2.1.2.3" + Task = "Ensure chrony is enabled and running" + Test = { + $testchr = dpkg-query -s chrony + $statuschr = $? + if ($statuschr -match "True") { + $result1 = systemctl is-enabled chrony.service + $result2 = systemctl is-active chrony.service + if ($result1 -match "enabled" -and $result2 -match "active") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "chrony not installed" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "2.1.3.1" + Task = "Ensure systemd-timesyncd configured with authorized timeserver" + Test = { + + $testtime = dpkg-query -s systemd-timesyncd + $statustime = $? + if ($statustime -match "True") { + $command = @' +find /etc/systemd -type f -name '*timesyncd*' -exec grep -Ehl '^NTP=|^FallbackNTP=' {} + +'@ + $test = bash -c $command + $status = $? + + if ($status -match "True") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "systemd-timesyncd not installed" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "2.1.3.2" + Task = "Ensure systemd-timesyncd is enabled and running" + Test = { + $result1 = systemctl is-enabled systemd-timesyncd.service + $result2 = systemctl is-active systemd-timesyncd.service + if ($result1 -match "enabled" -and $result2 -match "active") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.4.1" + Task = "Ensure ntp access control is configured" + Test = { + $testntp = dpkg-query -s ntp + $statusntp = $? + + if ($statusntp -match "True") { + $result = grep -P -- '^\h*restrict\h+((-4\h+)?|-6\h+)default\h+(?:[^#\n\r]+\h+)*(?!(?:\2|\3|\4|\5))(\h*\bkod\b\h*|\h*\bnomodify\b\h*|\h*\bnotrap\b\h*|\h*\bnopeer\b\h*|\h*\bnoquery\b\h*)\h+(?:[^#\n\r]+\h+)*(?!(?:\1|\3|\4|\5))(\h*\bkod\b\h*|\h*\bnomodify\b\h*|\h*\bnotrap\b\h*|\h*\bnopeer\b\h*|\h*\bnoquery\b\h*)\h+(?:[^#\n\r]+\h+)*(?!(?:\1|\2|\4|\5))(\h*\bkod\b\h*|\h*\bnomodify\b\h*|\h*\bnotrap\b\h*|\h*\bnopeer\b\h*|\h*\bnoquery\b\h*)\h+(?:[^#\n\r]+\h+)*(?!(?:\1|\2|\3|\5))(\h*\bkod\b\h*|\h*\bnomodify\b\h*|\h*\bnotrap\b\h*|\h*\bnopeer\b\h*|\h*\bnoquery\b\h*)\h+(?:[^#\n\r]+\h+)*(?!(?:\1|\2|\3|\4))(\h*\bkod\b\h*|\h*\bnomodify\b\h*|\h*\bnotrap\b\h*|\h*\bnopeer\b\h*|\h*\bnoquery\b\h*)\h*(?:\h+\H+\h*)*(?:\h+#.*)?$' /etc/ntp.conf + $wordsToCheck = "default", "kod", "nomodify", "notrap", "nopeer", "noquery" + $pattern = "\b(" + ($wordsToCheck -join "|") + ")\b" + if ($result.Count -eq 2 -and $result[0] -match $pattern -and $result[1] -match $pattern) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "ntp not installed" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "2.1.4.2" + Task = "Ensure ntp is configured with authorized timeserver" + Test = { + $testntp = dpkg-query -s ntp + $statusntp = $? + if ($statusntp -match "True") { + $result = grep -P -- '^\h*(server|pool)\h+\H+' /etc/ntp.conf + $wordsToCheck = "default", "kod", "nomodify", "notrap", "nopeer", "noquery" + $pattern = "\b(" + ($wordsToCheck -join "|") + ")\b" + if ($result.Count -eq 2 -and $result[0] -match $pattern -and $result[1] -match $pattern) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "ntp not installed" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "2.1.4.3" + Task = "Ensure ntp is running as user ntp" + Test = { + $testntp = dpkg-query -s ntp + $statusntp = $? + if ($statusntp -match "True") { + $result1 = ps -ef | awk '(/[n]tpd/ && $1!="ntp") { print $1 }' + $result2 = grep -P -- '^\h*RUNASUSER=' /etc/init.d/ntp + if ($result1 -eq $null -and $result2 -eq "RUNASUSER=ntp") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "ntp not installed" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "2.1.4.4" + Task = "Ensure ntp is enabled and running" + Test = { + $testntp = dpkg-query -s ntp + $statusntp = $? + if ($statusntp -match "True") { + $result1 = systemctl is-enabled ntp.service + $result2 = systemctl is-active ntp.service + if ($result1 -match "enabled" -and $result2 -match "active") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "ntp not installed" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "2.2.1" + Task = "Ensure X Window System is not installed" + Test = { + $result = dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' xserver-xorg* | grep -Pi '\h+installed\b' + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "Ensure Avahi Server is not installed" + Test = { + $test1 = dpkg -l | grep "^ii" | grep -q "avahi-daemon" + $test1 = $? + if ($test1 -match "False") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.3" + Task = "Ensure CUPS is not installed" + Test = { + $result = dpkg-query -s cups + $status = $? + if ($status -match "False") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.4" + Task = "Ensure DHCP Server is not installed" + Test = { + $result = dpkg -l | grep -o isc-dhcp-server + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.5" + Task = "Ensure LDAP server is not installed" + Test = { + $result = dpkg -l | grep -o slapd + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.6" + Task = "Ensure NFS is not installed" + Test = { + $result = dpkg -l | grep -o nfs-kernel-server + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.7" + Task = "Ensure DNS Server is not installed" + Test = { + $result = dpkg -l | grep -E -w "^ii\s+bind9\s" + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.8" + Task = "Ensure FTP Server is not installed" + Test = { + $result = dpkg -l | grep -o vsftpd + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.9" + Task = "Ensure HTTP server is not installed" + Test = { + $result = dpkg -l | grep -E 'apache2\s' + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.10" + Task = "Ensure IMAP and POP3 server are not installed" + Test = { + $result = dpkg -l | grep -o dovecot- + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.11" + Task = "Ensure Samba is not installed" + Test = { + $result = dpkg-query -s samba + $status = $? + if ($status -match "False") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.12" + Task = "Ensure HTTP Proxy Server is not installed" + Test = { + $result = dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' squid + if ($result -match "squid\s+unknown ok not-installed\s+not-installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.13" + Task = "Ensure SNMP Server is not installed" + Test = { + $result = dpkg -l | grep -E 'snmpd\s' + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.14" + Task = "Ensure NIS Server is not installed" + Test = { + $result = dpkg-query -s nis + $status = $? + if ($status -match "False") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.15" + Task = "Ensure mail transfer agent is configured for local-only mode" + Test = { + $result = ss -lntu | grep -E ':25\s' | grep -E -v '\s(127.0.0.1|::1):25\s' + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.16" + Task = "Ensure rsync service is either not installed or masked" + Test = { + $result = dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' rsync + if ($result -match "rsync\s+unknown ok not-installed\s+not-installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.3.1" + Task = "Ensure NIS Client is not installed" + Test = { + $result = dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' nis + if ($result -match "nis\s+unknown ok not-installed\s+not-installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.3.2" + Task = "Ensure rsh client is not installed" + Test = { + $result = dpkg-query -s rsh-client + $status = $? + if ($status -match "False") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.3.3" + Task = "Ensure talk client is not installed" + Test = { + $test1 = dpkg -l | grep "^ii" | grep -q "talk" + $test1 = $? + if ($test1 -match "False") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.3.4" + Task = "Ensure telnet client is not installed" + Test = { + $test1 = dpkg -l | grep -o telnet + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.3.5" + Task = "Ensure LDAP client is not installed" + Test = { + $test1 = dpkg -l | grep -o ldap-utils + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.3.6" + Task = "Ensure RPC is not installed" + Test = { + $test1 = dpkg -l | grep -o rpcbind + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.4" + Task = "Ensure nonessential services are removed or masked" + Test = { + $test1 = lsof -i -P -n | grep -v "(ESTABLISHED)" + if ($test1 -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.1.1" + Task = "Ensure system is checked to determine if IPv6 is enabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.1.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.1.2" + Task = "Ensure wireless interfaces are disabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.2.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.1.3" + Task = "Ensure DCCP is disabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.3.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.1.4" + Task = "Ensure SCTP is disabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.4.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.1.5" + Task = "Ensure RDS is disabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.5.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.1.6" + Task = "Ensure TIPC is disabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.6.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.2.1" + Task = "Ensure packet redirect sending is disabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.2.1.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.2.2" + Task = "Ensure IP forwarding is disabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.2.2.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.1" + Task = "Ensure source routed packets are not accepted" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.1.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.2" + Task = "Ensure ICMP redirects are not accepted" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.2.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.3" + Task = "Ensure secure ICMP redirects are not accepted" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.3.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.4" + Task = "Ensure suspicious packets are logged" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.4.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.5" + Task = "Ensure broadcast ICMP requests are ignored" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.5.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.6" + Task = "Ensure bogus ICMP responses are ignored" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.6.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.7" + Task = "Ensure Reverse Path Filtering is enabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.7.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.8" + Task = "Ensure TCP SYN Cookies is enabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.8.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.9" + Task = "Ensure IPv6 router advertisements are not accepted" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.9.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.1.1" + Task = "Ensure ufw is installed" + Test = { + $testnft = dpkg-query -s nftables + $statusnft = $? + if ($statusnft -match "False") { + $result = dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' ufw + if ($result -match "ufw\s+install ok installeds\+installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "nftables installed instead " + Status = "None" + } + } +} +[AuditTest] @{ + Id = "3.5.1.2" + Task = "Ensure iptables-persistent is not installed with ufw" + Test = { + $testufw = dpkg-query -s ufw + $statusufw = $? + if ($statusufw -match "True") { + $test1 = dpkg -l | grep -o iptables-persistent + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.5.1.3" + Task = "Ensure ufw service is enabled" + Test = { + $testnft = dpkg-query -s nftables + $statusnft = $? + if ($statusnft -match "True") { + return @{ + Message = "nftables installed instead " + Status = "None" + } + } + $result1 = systemctl is-enabled ufw.service + $result2 = systemctl is-active ufw + $result3 = ufw status + + if ($result1 -match "enabled" -and $result2 -match "active" -and $result3 -match "Status: active") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.1.4" + Task = "Ensure ufw loopback traffic is configured" + Test = { + $testnft = dpkg-query -s nftables + $statusnft = $? + if ($statusnft -match "True") { + return @{ + Message = "nftables installed instead " + Status = "None" + } + } + $test1 = ufw status verbose + $result1 = $test1 -match "^Anywhere on lo\s+ALLOW IN\s+Anywhere$" + $result2 = $test1 -match "^Anywhere\s+DENY IN\s+127.0.0.0/8$" + $result3 = $test1 -match "^Anywhere (v6) on lo\s+ALLOW IN\s+Anywhere (v6)$" + $result4 = $test1 -match "^Anywhere (v6)\s+DENY IN\s+::1$" + $result5 = $test1 -match "^Anywhere\s+ALLOW OUT\s+Anywhere on lo$" + $result6 = $test1 -match "^Anywhere (v6)\s+ALLOW OUT\s+Anywhere (v6) on lo$" + if ($result1 -ne $null -and $result2 -ne $null -and $result3 -ne $null -and $result4 -ne $null -and $result5 -ne $null -and $result6 -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.1.5" + Task = "Ensure ufw outbound connections are configured" + Test = { + $testnft = dpkg-query -s nftables + $statusnft = $? + if ($statusnft -match "True") { + return @{ + Message = "nftables installed instead " + Status = "None" + } + } + return @{ + Message = "Run the following command and verify all rules for new outbound connections match site policy: ufw status numbered" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "3.5.1.6" + Task = "Ensure ufw firewall rules exist for all open ports" + Test = { + $testnft = dpkg-query -s nftables + $statusnft = $? + if ($statusnft -match "True") { + return @{ + Message = "nftables installed instead " + Status = "None" + } + } + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/CIS-Ubuntu22.04_LTS-3.5.1.6.sh" + $result = bash $path + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.1.7" + Task = "Ensure ufw default deny firewall policy" + Test = { + + $testnft = dpkg-query -s nftables + $statusnft = $? + if ($statusnft -match "True") { + return @{ + Message = "nftables installed instead " + Status = "None" + } + } + + $result = ufw status verbose | grep Default: + + if ($result -match "Default: (deny|reject|disabled) (incoming), (deny|reject|disabled) (outgoing), (deny|reject|disabled) (routed)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.2.1" + Task = "Ensure nftables is installed" + Test = { + $test = dpkg-query -s nftables | grep 'Status: install ok installed' + if ($test -match "Status: install ok installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.2.2" + Task = "Ensure ufw is uninstalled or disabled with nftables" + Test = { + $testnft = dpkg-query -s nftables + $statusnft = $? + if ($statusnft -match "True") { + $testufw = dpkg-query -s ufw | grep 'Status: install ok installed' + $statusufw = $? + + if ($statusufw -match "True") { + $test2 = ufw status + if ($test2 -match "inactive") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "nftables not installed" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "3.5.2.3" + Task = "Ensure iptables are flushed with nftables" + Test = { + return @{ + Message = "Run the following commands to ensure no iptables rules exist for iptables: iptables -L \nNo rules should be returned for ip6tables: ip6tables -L \nNo rules should be returned" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "3.5.2.4" + Task = "Ensure a nftables table exists" + Test = { + $testnft = dpkg-query -s nftables + $statusnft = $? + if ($statusnft -match "True") { + $test = nft list tables + if ($test -match "table") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "nftables not installed" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "3.5.2.5" + Task = "Ensure nftables base chains exist" + Test = { + try { + $test1 = nft list ruleset | grep 'hook input' + $test2 = nft list ruleset | grep 'hook forward' + $test3 = nft list ruleset | grep 'hook output' + if ($test1 -match "type filter hook input" -and $test2 -match "type filter hook forward" -and $test3 -match "type filter hook output") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "nft not installed!" + Status = "None" + } + } + } +} +[AuditTest] @{ + Id = "3.5.2.6" + Task = "Ensure nftables loopback traffic is configured" + Test = { + try { + if ($isIPv6Disabled -ne $true) { + $test1 = nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept' + $test2 = nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr' + if ($test1 -match 'iif "lo" accept' -and $test2 -match "ip saddr 127.0.0.0/8 counter packets 0 bytes 0 drop") { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + else { + $test = nft list ruleset | awk '/hook input/,/}/' | grep 'ip6 saddr' + if ($test -match 'ip6 saddr ::1 counter packets 0 bytes 0 drop') { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "nft not installed!" + Status = "None" + } + } + } +} +[AuditTest] @{ + Id = "3.5.2.7" + Task = "Ensure nftables outbound and established connections are configured" + Test = { + try { + $test1 = nft list ruleset | awk '/hook input/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + $test2 = nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + if ($test1 -match "ip protocol tcp ct state established accept" -and $test1 -match "p protocol udp ct state established accept" -and $test1 -match "ip protocol icmp ct state established accept" -and $test2 -match "ip protocol tcp ct state established,related,new accep" -and $test2 -match "ip protocol udp ct state established,related,new accept" -and $test2 -match "ip protocol icmp ct state established,related,new accept") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "nft not installed!" + Status = "None" + } + } + } +} +[AuditTest] @{ + Id = "3.5.2.8" + Task = "Ensure nftables default deny firewall policy" + Test = { + try { + $test1 = nft list ruleset | grep 'hook input' + $test2 = nft list ruleset | grep 'hook forward' + $test3 = nft list ruleset | grep 'hook output' + if ($test1 -match "policy drop" -and $test2 -match "policy drop" -and $test3 -match "policy drop") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "nft not installed!" + Status = "None" + } + } + } +} +[AuditTest] @{ + Id = "3.5.2.9" + Task = "Ensure nftables service is enabled" + Test = { + $testnft = dpkg-query -s nftables + $statusnft = $? + if ($statusnft -match "True") { + $test1 = systemctl is-enabled nftables + if ($test1 -match "enabled") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "nftables not installed" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "3.5.3.1.1" + Task = "Ensure iptables packages are installed" + Test = { + $testnft = dpkg-query -s nftables + $statusnft = $? + if ($statusnft -match "False") { + $test1 = apt list iptables iptables-persistent + $test1 = $? + if ($test1 -match "True") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "nftables installed instead" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "3.5.3.1.2" + Task = "Ensure nftables is not installed with iptables" + Test = { + + $testipt = dpkg-query -s iptables | grep 'Status: install ok installed' + $statusipt = $? + $testnft = dpkg-query -s nftables | grep 'Status: install ok installed' + $statusnft = $? + + if ($statusipt -match "True") { + if ($statusnft -match "True") { + $test1 = dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' nftables + if ($test1 -match "nftables\s+unknown ok not-installed\s+not-installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "iptables not installed " + Status = "None" + } + } +} +[AuditTest] @{ + Id = "3.5.3.1.3" + + Task = "Ensure ufw is uninstalled or disabled with iptables" + Test = { + + $testipt = dpkg-query -s iptables | grep 'Status: install ok installed' + $statusipt = $? + $testufw = dpkg-query -s ufw | grep 'Status: install ok installed' + $statusufw = $? + + if ($statusipt -match "True") { + if ($statusufw -match "True") { + $test1 = dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' ufw + $test2 = ufw status + $test3 = systemctl is-enabled ufw + if ($test1 -match "ufw\s+unknown ok not-installed\s+not-installed" -and $test2 -match "Status: inactive" -and $test3 -match "masked") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "iptables not installed " + Status = "None" + } + + } +} +[AuditTest] @{ + Id = "3.5.3.2.1" + Task = "Ensure iptables default deny firewall policy" + Test = { + $test1 = iptables -L + if ($test1 -match "Chain INPUT (policy (DROP|REJCET))" -and $test1 -match "Chain FORWARD (policy (DROP|REJCET))" -and $test1 -match "Chain OUTPUT (policy (DROP|REJCET))") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.3.2.2" + Task = "Ensure iptables loopback traffic is configured" + Test = { + $test1 = iptables -L INPUT -v -n | grep "Chain\s*INPUT\s*(policy\s*DROP" + $test2 = iptables -L OUTPUT -v -n | grep "Chain\s*OUTPUT\s*(policy\s*DROP" + if ($test1 -ne $null -and $test2 -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.3.2.4" + Task = "Ensure iptables firewall rules exist for all open ports" + Test = { + $test1 = ss -4tuln + if ($test1 -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.3.3.1" + Task = "Ensure ip6tables default deny firewall policy" + Test = { + $test1 = ip6tables -L + if ($test1 -match "Chain INPUT (policy (DROP|REJCET))" -and $test1 -match "Chain FORWARD (policy (DROP|REJCET))" -and $test1 -match "Chain OUTPUT (policy (DROP|REJCET))") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.3.3.3" + Task = "Ensure ip6tables outbound and established connections are configured" + Test = { + return @{ + Message = "Run the following command and verify all rules for new outbound, and established connections match site policy: ip6tables -L -v -n" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "4.1.1.1" + Task = "Ensure auditd is installed" + Test = { + $test = dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' auditd audispd-plugins + if ($test -match "audispd-plugins\s+install ok installed\s+installed" -and $test -match "auditd\s+install ok installed\s+installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.1.2" + Task = "Ensure auditd service is enabled and active" + Test = { + $test1 = systemctl is-enabled auditd + $test2 = systemctl is-active auditd + if ($test1 -match "enabled" -and $test2 -match "active") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.1.3" + Task = "Ensure auditing for processes that start prior to auditd is enabled" + Test = { + $command = @' + find /boot -type f -name 'grub.cfg' -exec grep -Ph -- '^\h*linux' {} + | grep -v 'audit=1' +'@ + $test = bash -c $command + if ($test -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.1.4" + Task = "Ensure audit_backlog_limit is sufficient" + Test = { + $command = @' + find /boot -type f -name 'grub.cfg' -exec grep -Ph -- '^\h*linux' {} + | grep -Pv 'audit_backlog_limit=\d+\b' +'@ + $test = bash -c $command + if ($test -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.2.1" + Task = "Ensure audit log storage size is configured" + Test = { + $test = grep -Po -- '^\h*max_log_file\h*=\h*\d+\b' /etc/audit/auditd.conf + if ($test -match "max_log_file =") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.2.2" + Task = "Ensure audit logs are not automatically deleted" + Test = { + $test = grep max_log_file_action /etc/audit/auditd.conf + if ($test -match "max_log_file_action = keep_logs") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.2.3" + Task = "Ensure system is disabled when audit logs are full" + Test = { + $test1 = grep space_left_action /etc/audit/auditd.conf + $test2 = grep action_mail_acct /etc/audit/auditd.conf + $test3 = grep -E 'admin_space_left_action\s*=\s*(halt|single)' /etc/audit/auditd.conf + if ($test1 -match "space_left_action = email" -and $test2 -match "action_mail_acct = root" -and $test3 -match "admin_space_left_action = (halt|single)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.3.1" + Task = "Ensure changes to system administration scope (sudoers) is collected" + Test = { + try { + $res1 = awk '/^ *-w/ &&/\/etc\/sudoers/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules | grep -- "-w /etc/sudoers -p wa -k scope" + $res2 = awk '/^ *-w/ &&/\/etc\/sudoers/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules | grep -- "-w /etc/sudoers.d -p wa -k scope" + $res3 = auditctl -l | awk '/^ *-w/ &&/\/etc\/sudoers/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' | grep -- "-w /etc/sudoers -p wa -k scope" + $res4 = auditctl -l | awk '/^ *-w/ &&/\/etc\/sudoers/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' | grep -- "-w /etc/sudoers.d -p wa -k scope" + if ($res1 -ne $null -and $res2 -ne $null -and $res3 -ne $null -and $res4 -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.3.2" + Task = "Ensure actions as another user are always logged" + Test = { + $test1 = awk '/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&(/ -C *euid!=uid/||/ -C *uid!=euid/) &&/ -S *execve/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules + try { + $test2 = auditctl -l | awk '/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&(/ -C *euid!=uid/||/ -C *uid!=euid/) &&/ -S *execve/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' + } + catch { + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + if ($test1 -match "-a always,exit -F arch=b64 -C euid!=uid -F auid!=unset -S execve -k user_emulation" -and $test1 -match "-a always,exit -F arch=b32 -C euid!=uid -F auid!=unset -S execve -k user_emulation" -and $test2 -match "-a always,exit -F arch=b64 -S execve -C uid!=euid -F auid!=-1 -F key=user_emulation" -and $test2 -match "-a always,exit -F arch=b32 -S execve -C uid!=euid -F auid!=-1 -F key=user_emulation") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.3.3" + Task = "Ensure events that modify the sudo log file are collected" + Test = { + $command1 = @' +SUDO_LOG_FILE_ESCAPED=$(grep -r logfile /etc/sudoers* | sed -e 's/.*logfile=//;s/,? .*//' -e 's/"//g' -e 's|/|\\/|g') [ -n "${SUDO_LOG_FILE_ESCAPED}" ] && awk "/^ *-w/ \ &&/"${SUDO_LOG_FILE_ESCAPED}"/ \ &&/ +-p *wa/ \ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules \ || printf "ERROR: Variable 'SUDO_LOG_FILE_ESCAPED' is unset.\n" +'@ + $command2 = @' +SUDO_LOG_FILE_ESCAPED=$(grep -r logfile /etc/sudoers* | sed -e 's/.*logfile=//;s/,? .*//' -e 's/"//g' -e 's|/|\\/|g') [ -n "${SUDO_LOG_FILE_ESCAPED}" ] && auditctl -l | awk "/^ *-w/ \ &&/"${SUDO_LOG_FILE_ESCAPED}"/ \ &&/ +-p *wa/ \ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" \ || printf "ERROR: Variable 'SUDO_LOG_FILE_ESCAPED' is unset.\n" +'@ + $test1 = bash -c $command1 + $test2 = bash -c $command2 + if ($test1 -match "-w /var/log/sudo.log -p wa -k sudo_log_file" -and $test2 -match "-w /var/log/sudo.log -p wa -k sudo_log_file") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.3.4" + Task = "Ensure events that modify date and time information are collected" + Test = { + $test1 = { awk '/^ *-a *always,exit/ \ &&/ -F *arch=b[2346]{2}/ \ &&/ -S/ \ &&(/adjtimex/ \ ||/settimeofday/ \ ||/clock_settime/ ) \ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules awk '/^ *-w/ \ &&/\/etc\/localtime/ \ &&/ +-p *wa/ \ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules } + $test2 = { auditctl -l | awk '/^ *-a *always,exit/ \ &&/ -F *arch=b[2346]{2}/ \ &&/ -S/ \ &&(/adjtimex/ \ ||/settimeofday/ \ ||/clock_settime/ ) \ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' auditctl -l | awk '/^ *-w/ \ &&/\/etc\/localtime/ \ &&/ +-p *wa/ \ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' } + if ($test1 -match "-a always,exit -F arch=b64 -S adjtimex,settimeofday clock_settime -k time-change" -and $test1 -match "-a always,exit -F arch=b32 -S adjtimex,settimeofday,clock_settime -k time-change" -and $test1 -match "-w /etc/localtime -p wa -k time-change" -and $test2 -match "-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -F key=time-change" -and $test2 -match "-a always,exit -F arch=b32 -S adjtimex,settimeofday clock_settime -F key=time-change" -and $test3 -match "-w /etc/localtime -p wa -k time-change") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.3.5" + Task = "Ensure events that modify the system's network environment are collected" + Test = { + $test1 = awk '/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&/ -S/ &&(/sethostname/ ||/setdomainname/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules + $test2 = awk "/^ *-w/ &&(/\/etc\/issue/ ||/\/etc\/issue.net/ ||/\/etc\/hosts/ ||/\/etc\/network/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules + try { + $test3 = auditctl -l | awk '/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&/ -S/ &&(/sethostname/ ||/setdomainname/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' + $test4 = auditctl -l | awk '/^ *-w/ &&(/\/etc\/issue/ ||/\/etc\/issue.net/ ||/\/etc\/hosts/ ||/\/etc\/network/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' + } + catch { + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + if ($test1 -match "-a always,exit -F arch=b64 -S adjtimex,settimeofday clock_settime -k time-change" -and $test1 -match "-a always,exit -F arch=b32 -S adjtimex,settimeofday,clock_settime -k time-change" -and $test1 -match "-w /etc/localtime -p wa -k time-change" -and $test2 -match "-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -F key=time-change" -and $test2 -match "-a always,exit -F arch=b32 -S adjtimex,settimeofday clock_settime -F key=time-change" -and $test3 -match "-w /etc/localtime -p wa -k time-change") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.3.6" + Task = "Ensure use of privileged commands are collected" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path1 = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.3.6-A.sh" + $result1 = bash $path1 | grep "Warning" + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path2 = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.3.6-B.sh" + $result2 = bash $path2 | grep "Warning" + if ($result1 -eq $null -and $result2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.3.8" + Task = "Ensure events that modify user/group information are collected" + Test = { + + try { + $dummy = auditctl -l + } + catch { + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + + $output1 = awk '/^ *-w/ \ + &&(/\/etc\/group/ \ + ||/\/etc\/passwd/ \ + ||/\/etc\/gshadow/ \ + ||/\/etc\/shadow/ \ + ||/\/etc\/security\/opasswd/) \ + &&/ +-p *wa/ \ + &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules + $result11 = $output1 | grep "\-w /etc/group -p wa -k identity" + $result12 = $output1 | grep "\-w /etc/passwd -p wa -k identity" + $result13 = $output1 | grep "\-w /etc/gshadow -p wa -k identity" + $result14 = $output1 | grep "\-w /etc/shadow -p wa -k identity" + $result15 = $output1 | grep "\-w /etc/security/opasswd -p wa -k identity" + $output2 = auditctl -l | awk '/^ *-w/ \ + &&(/\/etc\/group/ \ + ||/\/etc\/passwd/ \ + ||/\/etc\/gshadow/ \ + ||/\/etc\/shadow/ \ + ||/\/etc\/security\/opasswd/) \ + &&/ +-p *wa/ \ + &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' + $result21 = $output2 | grep "\-w /etc/group -p wa -k identity" + $result22 = $output2 | grep "\-w /etc/passwd -p wa -k identity" + $result23 = $output2 | grep "\-w /etc/gshadow -p wa -k identity" + $result24 = $output2 | grep "\-w /etc/shadow -p wa -k identity" + $result25 = $output2 | grep "\-w /etc/security/opasswd -p wa -k identity" + if ($result11 -ne $null -and $result12 -ne $null -and $result13 -ne $null -and $result14 -and $result15 -ne $null -and $result21 -ne $null -and $result22 -ne $null -and $result23 -ne $null -and $result24 -ne $null -and $result25 -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.3.11" + Task = "Ensure session initiation information is collected" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path1 = $parentPath + "/Helpers/ShellScripts/CIS-Ubuntu22.04_LTS-4.1.3.11_1.sh" + $result11 = bash $path1 | grep "\-w /var/run/utmp -p wa -k session" + $result12 = bash $path1 | grep "\-w /var/log/wtmp -p wa -k session" + $result13 = bash $path1 | grep "\-w /var/log/btmp -p wa -k session" + $path2 = $parentPath + "/Helpers/ShellScripts/CIS-Ubuntu22.04_LTS-4.1.3.11_2.sh" + $result21 = bash $path2 | grep "\-w /var/run/utmp -p wa -k session" + $result22 = bash $path2 | grep "\-w /var/log/wtmp -p wa -k session" + $result23 = bash $path2 | grep "\-w /var/log/btmp -p wa -k session" + if ($result11 -ne $null -and $result12 -ne $null -and $result13 -ne $null -and $result21 -ne $null -and $result22 -ne $null -and $result23 -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.3.12" + Task = "Ensure login and logout events are collected" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path1 = $parentPath + "/Helpers/ShellScripts/CIS-Ubuntu22.04_LTS-4.1.3.12_1.sh" + $result11 = bash $path1 | grep "\-w /var/log/lastlog -p wa -k logins" + $result12 = bash $path1 | grep "\-w /var/run/faillock -p wa -k logins" + $path2 = $parentPath + "/Helpers/ShellScripts/CIS-Ubuntu22.04_LTS-4.1.3.12_2.sh" + $result21 = bash $path2 | grep "\-w /var/log/lastlog -p wa -k logins" + $result22 = bash $path2 | grep "\-w /var/run/faillock -p wa -k logins" + if ($result11 -ne $null -and $result12 -ne $null -and $result21 -ne $null -and $result22 -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.3.14" + Task = "Ensure events that modify the system's Mandatory Access Controls are collected" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path1 = $parentPath + "/Helpers/ShellScripts/CIS-Ubuntu22.04_LTS-4.1.3.14_1.sh" + $result11 = bash $path1 | grep "\-w /etc/apparmor/ -p wa -k MAC-policy" + $result12 = bash $path1 | grep "\-w /etc/apparmor.d/ -p wa -k MAC-policy" + $path2 = $parentPath + "/Helpers/ShellScripts/CIS-Ubuntu22.04_LTS-4.1.3.14_2.sh" + $result21 = bash $path2 | grep "\-w /etc/apparmor/ -p wa -k MAC-policy" + $result22 = bash $path2 | grep "\-w /etc/apparmor.d/ -p wa -k MAC-policy" + if ($result11 -ne $null -and $result12 -ne $null -and $result21 -ne $null -and $result22 -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.3.20" + Task = "Ensure events that modify the system's Mandatory Access Controls are collected" + Test = { + $test = grep -Ph -- '^\h*-e\h+2\b' /etc/audit/rules.d/*.rules | tail -1 + if ($test -match "-e 2") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.3.21" + Task = "Ensure the running and on disk configuration is the same" + Test = { + return @{ + Message = "Ensure that all rules in /etc/audit/rules.d have been merged into /etc/audit/audit.rules: augenrules --check \n/usr/sbin/augenrules: No change \nShould there be any drift, run augenrules --load to merge and load all rules." + Status = "None" + } + } +} +[AuditTest] @{ + Id = "4.1.4.1" + Task = "Ensure audit log files are mode 0640 or less permissive" + Test = { + $command = @' +dir=$(awk -F= '/^log_file/ {print $2}' /etc/audit/auditd.conf | xargs dirname) && [ $(stat -c "%a" "$dir") -le 640 ] && echo "PASS: Directory permissions are 0640 or less permissive" || echo "FAIL: Directory permissions are more permissive" +'@ + $result = bash -c $command + if ($result -match " PASS ") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.4.2" + Task = "Ensure only authorized users own audit log files" + Test = { + $test1 = stat -Lc "%n %U" "$(dirname $(awk -F"=" '/^\s*log_file\s*=\s*/ {print $2}' /etc/audit/auditd.conf | xargs))"/* | grep -Pv -- '^\H+\h+root\b' + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.4.3" + Task = "Ensure only authorized groups are assigned ownership of audit log files" + Test = { + $test1 = grep -Piw -- '^\h*log_group\h*=\h*(adm|root)\b' /etc/audit/auditd.conf + $test2 = stat -c "%n %G" "$(dirname $(awk -F"=" '/^\s*log_file\s*=\s*/ {print $2}' /etc/audit/auditd.conf | xargs))"/* | grep -Pv '^\h*\H+\h+(adm|root)\b' + if ($test1 -match "(log_group = adm)|(log_group = root)" -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.4.4" + Task = "Ensure the audit log directory is 0750 or more restrictive" + Test = { + $test1 = stat -Lc "%n %a" "$(dirname $( awk -F"=" '/^\s*log_file/ {print $2}' /etc/audit/auditd.conf))" | grep -Pv -- '^\h*\H+\h+([0,5,7][0,5]0)' + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.4.5" + Task = "Ensure audit configuration files are 640 or more restrictive" + Test = { + $command = @' + find /etc/audit/ -type f \( -name '*.conf' -o -name '*.rules' \) -exec stat -Lc "%n %a" {} + | grep -Pv -- '^\h*\H+\h*([0,2,4,6][0,4]0)\h*$' +'@ + $test1 = bash -c $command + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.4.6" + Task = "Ensure audit configuration files are owned by root" + Test = { + $command = @' +find /etc/audit/ -type f \( -name '*.conf' -o -name '*.rules' \) ! -user root +'@ + $test1 = bash -c $command + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.4.7" + Task = "Ensure audit configuration files belong to group root" + Test = { + $command = @' +find /etc/audit/ -type f \( -name '*.conf' -o -name '*.rules' \) ! -group root +'@ + $test1 = bash -c $command + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.4.8" + Task = "Ensure audit tools are 755 or more restrictive" + Test = { + $test1 = stat -c "%n %a" /sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules | grep -Pv -- '^\h*\H+\h+([0-7][0,1,4,5][0,1,4,5])\h*$' + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.4.9" + Task = "Ensure audit tools are owned by root" + Test = { + $test1 = stat -c "%n %U" /sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules | grep -Pv -- '^\h*\H+\h+root\h*$' + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.4.10" + Task = "Ensure audit tools belong to group root" + Test = { + $test1 = stat -c "%n %a %U %G" /sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules | grep -Pv -- '^\h*\H+\h+([0-7][0,1,4,5][0,1,4,5])\h+root\h+root\h*$' + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.4.11" + Task = "Ensure cryptographic mechanisms are used to protect the integrity of audit tools" + Test = { + $test1 = grep -Ps -- '(\/sbin\/(audit|au)\H*\b)' /etc/aide/aide.conf.d/*.conf /etc/aide/aide.conf + if ($test1 -match "/sbin/auditctl p+i+n+u+g+s+b+acl+xattrs+sha512" -and + $test1 -match "/sbin/auditd p+i+n+u+g+s+b+acl+xattrs+sha512" -and + $test1 -match "/sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512" -and + $test1 -match "/sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512" -and + $test1 -match "/sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512" -and + $test1 -match "/sbin/augenrules p+i+n+u+g+s+b+acl+xattrs+sha512") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.1.1.1" + Task = "Ensure systemd-journal-remote is installed" + Test = { + $test1 = dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' systemd-journal-remote + if ($test1 -match "systemd-journal-remote\s+install ok installed\s+installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.1.1.2" + Task = "Ensure systemd-journal-remote is configured" + Test = { + return @{ + Message = 'Verify systemd-journal-remote is configured. Run the following command: grep -P "^ *URL=|^ *ServerKeyFile=|^ *ServerCertificateFile=|^ *TrustedCertificateFile=" /etc/systemd journal-upload.conf' + Status = "None" + } + } +} +[AuditTest] @{ + Id = "4.2.1.1.3" + Task = "Ensure systemd-journal-remote is enabled" + Test = { + $test1 = systemctl is-enabled systemd-journal-upload.service + if ($test1 -match "enabled") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.1.1.4" + Task = "Ensure journald is not configured to recieve logs from a remote client" + Test = { + $test1 = systemctl is-enabled systemd-journal-remote.socket + if ($test1 -match "disabled") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.1.2" + Task = "Ensure journald service is enabled" + Test = { + $test1 = systemctl is-enabled systemd-journald.service + if ($test1 -match "static") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.1.3" + Task = "Ensure journald is configured to compress large log files" + Test = { + $test1 = grep ^\s*Compress /etc/systemd/journald.conf + if ($test1 -match "Compress=yes") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.1.4" + Task = "Ensure journald is configured to write logfiles to persistent disk" + Test = { + $test1 = grep ^\s*Storage /etc/systemd/journald.conf + if ($test1 -match "Storage=persistent") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.1.5" + Task = "Ensure journald is not configured to send logs to rsyslog" + Test = { + $test1 = grep ^\s*ForwardToSyslog /etc/systemd/journald.conf + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.1.6" + Task = "Ensure journald log rotation is configured per site policy" + Test = { + return @{ + Message = "Review /etc/systemd/journald.conf and verify logs are rotated according to site policy. The specific parameters for log rotation are:\n + SystemMaxUse=\n + SystemKeepFree=\n + RuntimeMaxUse=\n + RuntimeKeepFree=\n + MaxFileSec=" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "4.2.1.7" + Task = "Ensure journald default file permissions configured" + Test = { + return @{ + Message = "First see if there is an override file /etc/tmpfiles.d/systemd.conf. If so, this file will override all default settings as defined in /usr/lib/tmpfiles.d/systemd.conf and should be inspected. If there is no override file, inspect the default /usr/lib/tmpfiles.d/systemd.conf against the site specific requirements. Ensure that file permissions are 0640. Should a site policy dictate less restrictive permissions, ensure to follow said policy. NOTE: More restrictive permissions such as 0600 is implicitly sufficient." + Status = "None" + } + } +} +[AuditTest] @{ + Id = "4.2.2.1" + Task = "Ensure rsyslog is installed" + Test = { + $test1 = dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' rsyslog + if ($test1 -match "rsyslog\s+install ok installed\s+installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.2.2" + Task = "Ensure rsyslog service is enabled" + Test = { + $test1 = systemctl is-enabled rsyslog + if ($test1 -match "enabled") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.2.3" + Task = "Ensure journald is configured to send logs to rsyslog" + Test = { + $test1 = grep ^\s*ForwardToSyslog /etc/systemd/journald.conf + if ($test1 -match "ForwardToSyslog=yes") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.2.4" + Task = "Ensure rsyslog default file permissions are configured" + Test = { + $test1 = grep ^\$FileCreateMode /etc/rsyslog.conf /etc/rsyslog.d/*.conf + if ($test1 -match "$FileCreateMode 0640") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.2.6" + Task = "Ensure rsyslog is configured to send logs to a remote log host" + Test = { + return @{ + Message = "Review the /etc/rsyslog.conf and /etc/rsyslog.d/*.conf files and verify that logs are sent to a central host (where loghost.example.com is the name of your central log host):" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "4.2.2.7" + Task = "Ensure rsyslog is not configured to receive logs from a remote client" + Test = { + $test1 = grep -s '$ModLoad imtcp' /etc/rsyslog.conf /etc/rsyslog.d/*.conf + $test2 = grep -s '$InputTCPServerRun' /etc/rsyslog.conf /etc/rsyslog.d/*.conf + if ($test1 -eq $null -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.3" + Task = "Ensure all logfiles have appropriate permissions and ownership" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-4.2.3.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.2.7" + Task = "Ensure rsyslog is not configured to receive logs from a remote client" + Test = { + $test1 = grep '$ModLoad imtcp' /etc/rsyslog.conf /etc/rsyslog.d/*.conf + $test2 = grep '$InputTCPServerRun' /etc/rsyslog.conf /etc/rsyslog.d/*.conf + if ($test1 -eq $null -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.1" + Task = "Ensure cron daemon is enabled and running" + Test = { + $test1 = systemctl is-enabled cron + $test2 = systemctl status cron | grep 'Active: active (running) ' + if ($test1 -eq "enabled" -and $test2 -match "running") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.2" + Task = "Ensure permissions on /etc/crontab are configured" + Test = { + $test1 = stat /etc/crontab | grep 0600 + if ($test1 -ne $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.3" + Task = "Ensure permissions on /etc/cron.hourly are configured" + Test = { + $test1 = stat /etc/cron.hourly/ + if ($test1 -eq "Access: (0700/drwx------) Uid: ( 0/ root) Gid: ( 0/ root)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.4" + Task = "Ensure permissions on /etc/cron.daily are configured" + Test = { + $test1 = stat /etc/cron.daily/ + if ($test1 -eq "Access: (0700/drwx------) Uid: ( 0/ root) Gid: ( 0/ root)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.5" + Task = "Ensure permissions on /etc/cron.weekly are configured" + Test = { + $test1 = stat /etc/cron.weekly/ + if ($test1 -eq "Access: (0700/drwx------) Uid: ( 0/ root) Gid: ( 0/ root)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.6" + Task = "Ensure permissions on /etc/cron.monthly are configured" + Test = { + $test1 = stat /etc/cron.monthly/ + if ($test1 -eq "Access: (0700/drwx------) Uid: ( 0/ root) Gid: ( 0/ root)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.7" + Task = "Ensure permissions on /etc/cron.d are configured" + Test = { + $test1 = stat /etc/cron.d/ + if ($test1 -eq "Access: (0700/drwx------) Uid: ( 0/ root) Gid: ( 0/ root)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.8" + Task = "Ensure cron is restricted to authorized users" + Test = { + $test1 = stat /etc/cron.deny + $test1 = $? + $test2 = stat /etc/cron.allow + if ($test1 -match "False" -and $test2 -match "0640\s*.*Uid.*root.*Gid.*root") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.9" + Task = "Ensure at is restricted to authorized users" + Test = { + $test1 = stat /etc/at.deny + $test1 = $? + $test2 = stat /etc/at.allow | grep 0640 + if ($test1 -match "False" -and $test2 -eq "Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 0/ root)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.1" + Task = "Ensure permissions on /etc/ssh/sshd_config are configured" + Test = { + try { + try { + $test1 = stat /etc/ssh/sshd_config | grep 0600 + } + catch { + return @{ + Message = "Path not found!" + Status = "False" + } + } + + if ($test1 -eq "Access: (0600/-rw-------) Uid: ( 0/ root) Gid: ( 0/ root)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "Path not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.2.2" + Task = "Ensure permissions on SSH private host key files are configured" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-5.2.2.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.3" + Task = "Ensure permissions on SSH public host key files are configured" + Test = { + $res = bash -c "find /etc/ssh -xdev -type f -name 'ssh_host_*_key.pub' -exec stat {} \;" | grep "Access:\s*(0644/-rw-r--r--)\s*Uid:\s*(\s*0/\s*root)\s*Gid:\s*(\s*0/\s*root)\s*" + if ($res.count -eq 3) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.4" + Task = "Ensure SSH access is limited" + Test = { + try { + $result = bash -c "sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -Ei '^\s*(allow|deny)(users|groups)\s+\S+'" + if ($result -match "allowusers" -or $result -match "allowgroups" -or $result -match "denyusers" -or $result -match "denygroups") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.2.5" + Task = "Ensure SSH LogLevel is appropriate" + Test = { + try { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep loglevel + try { + $test2 = grep -is 'loglevel' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf | grep -Evi '(VERBOSE|INFO)' + } + catch { + return @{ + Message = "Path not found!" + Status = "False" + } + } + if (($test1 -match "loglevel VERBOSE" -or $test1 -match "loglevel INFO") -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.2.6" + Task = "Ensure SSH PAM is enabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i usepam + $test2 = grep -Ei '^\s*UsePAM\s+no' /etc/ssh/sshd_config + if ($test1 -match "usepam yes" -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.7" + Task = "Ensure SSH root login is disabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permitrootlogin + $test2 = grep -Ei '^\s*PermitRootLogin\s+no' /etc/ssh/sshd_config + if ($test1 -match "permitrootlogin no" -and $test2 -match "PermitRootLogin no") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.8" + Task = "Ensure SSH HostbasedAuthentication is disabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep hostbasedauthentication + $test2 = grep -Ei '^\s*HostbasedAuthentication\s+yes' /etc/ssh/sshd_config + if ($test1 -match "hostbasedauthentication no" -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.9" + Task = "Ensure SSH PermitEmptyPasswords is disabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permitemptypasswords + $test2 = grep -Ei '^\s*PermitEmptyPasswords\s+yes' /etc/ssh/sshd_config + if ($test1 -match "permitemptypasswords no" -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.10" + Task = "Ensure SSH PermitUserEnvironment is disabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permituserenvironment + $test2 = grep -Ei '^\s*PermitUserEnvironment\s+yes' /etc/ssh/sshd_config + if ($test1 -match "permituserenvironment no" -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.11" + Task = "Ensure SSH IgnoreRhosts is enabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep ignorerhosts + $test2 = grep -Ei '^\s*ignorerhosts\s+no\b' /etc/ssh/sshd_config + if ($test1 -match "ignorerhosts yes" -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.12" + Task = "Ensure SSH X11 forwarding is disabled" + Test = { + try { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i x11forwarding + try { + $test2 = grep -Eis '^\s*x11forwarding\s+yes' /etc/ssh/sshd_config/etc/ssh/sshd_config.d/*.conf + } + catch { + return @{ + Message = "Path not found!" + Status = "False" + } + } + if ($test1 -match "x11forwarding no" -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.2.13" + Task = "Ensure only strong Ciphers are used" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep ciphers + if ($test1 -notmatch "(3des-cbc|aes128-cbc|aes192-cbc|aes256-cbc)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.14" + Task = "Ensure only strong MAC algorithms are used" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i "MACs" + if ($test1 -notmatch "(hmac-md5|hmac-md5-96|hmac-ripemd160|hmac-sha1|hmac-sha1-96|umac-64@openssh.com|umac-128@openssh.com|hmac-md5-etm@openssh.com|hmac-md5-96-etm@openssh.com|hmac-ripemd160-etm@openssh.com|hmac-sha1-etm@openssh.com|hmac-sha1-96-etm@openssh.com|umac-64-etm@openssh.com|umac-128-etm@openssh.com)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.15" + Task = "Ensure only strong Key Exchange algorithms are used" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep kexalgorithms + if ($test1 -notmatch "(diffie-hellman-group1-sha1|diffie-hellman-group14-sha1|diffie-hellman-group-exchange-sha1)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.16" + Task = "Ensure SSH AllowTcpForwarding is disabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i allowtcpforwarding + $test2 = grep -Ei '^\s*AllowTcpForwarding\s+yes' /etc/ssh/sshd_config + if ($test1 -match "allowtcpforwarding no" -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.17" + Task = "Ensure SSH warning banner is configured" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep banner + if ($test1 -match "banner /etc/issue.net") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.18" + Task = "Ensure SSH MaxAuthTries is set to 4 or less" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep maxauthtries + $test2 = grep -Ei '^\s*maxauthtries\s+([5-9]|[1-9][0-9]+)' /etc/ssh/sshd_config + if ($test1 -match "maxauthtries 4" -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.19" + Task = "Ensure SSH MaxStartups is configured" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i maxstartups + $test2 = grep -Ei '^\s*maxstartups\s+(((1[1-9]|[1-9][0-9][0-9]+):([0-9]+):([0-9]+))|(([0-9]+):(3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):([0-9]+))|(([0-9]+):([0-9]+):(6[1-9]|[7-9][0-9]|[1-9][0-9][0-9]+)))' /etc/ssh/sshd_config + if ($test1 -match "maxstartups 10:30:60" -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.20" + Task = "Ensure SSH MaxSessions is set to 10 or less" + Test = { + try { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i maxsessions | cut -d ' ' -f 2 + + try { + $test2 = grep -Eis '^\s*MaxSessions\s+(1[1-9]|[2-9][0-9]|[1-9][0-9][0-9]+)'/etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch { + return @{ + Message = "Path not found!" + Status = "False" + } + } + if ($test1 -le 10 -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.2.21" + Task = "Ensure SSH LoginGraceTime is set to one minute or less" + Test = { + try { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep logingracetime | cut -d ' ' -f 2 + try { + $test2 = grep -Eis '^\s*LoginGraceTime\s+(0|6[1-9]|[7-9][0-9]|[1-9][0-9][0-9]+|[^1]m)' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch { + return @{ + Message = "Path not found!" + Status = "False" + } + } + if (($test1 -ge 1 -and $test1 -le 60) -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.2.22" + Task = "Ensure SSH Idle Timeout Interval is configured" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep clientaliveinterval + $test2 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep clientalivecountmax + if ($test1 -match "clientaliveinterval 15" -and $test2 -match "clientalivecountmax 3") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.3.1" + Task = "Ensure sudo is installed" + Test = { + $command = @' +dpkg-query -W sudo sudo-ldap > /dev/null 2>&1 && dpkg-query -W -f='${binary:Package}\t${Status}\t${db:Status-Status}\n' sudo sudo-ldap | awk '($4=="installed" && $NF=="installed") {print "\n""PASS:""\n""Package ""\""$1"\""" is installed""\n"}' || echo -e "\nFAIL:\nneither \"sudo\" or \"sudo-ldap\" package is installed\n" +'@ + $test1 = bash -c $command + if ($test1 -match "PASS:") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.3.2" + Task = "Ensure sudo commands use pty" + Test = { + $test1 = grep -rPi '^\h*Defaults\h+([^#\n\r]+,)?use_pty(,\h*\h+\h*)*\h*(#.*)?$' /etc/sudoers* + if ($test1 -match "/etc/sudoers:Defaults use_pty") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.3.3" + Task = "Ensure sudo log file exists" + Test = { + $command = @' + grep -rPsi "^\h*Defaults\h+([^#]+,\h*)?logfile\h*=\h*(\"|\')?\H+(\"|\')?(,\h*\H+\h*)*\h* (#.*)?$" /etc/sudoers* +'@ + $test1 = bash -c $command + + if ($test1 -eq $null) { + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + + + } +} +[AuditTest] @{ + Id = "5.3.4" + Task = "Ensure users must provide password for privilege escalation" + Test = { + $test1 = grep -r "^[^#].*NOPASSWD" /etc/sudoers* + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.3.5" + Task = "Ensure re-authentication for privilege escalation is not disabled globally" + Test = { + $test1 = grep -r "^[^#].*\!authenticate" /etc/sudoers* + if ($test1 -match '!authenticate') { + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.3.6" + Task = "Ensure sudo authentication timeout is configured correctly" + Test = { + #todo + $test1 = grep -roP "timestamp_timeout=\K[0-9]*" /etc/sudoers* + if ($test1 -match 'auth required pam_wheel.so use_uid group=') { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.3.7" + Task = "Ensure access to the su command is restricted" + Test = { + #todo + $test1 = grep -Pi '^\h*auth\h+(?:required|requisite)\h+pam_wheel\.so\h+(?:[^#\n\r]+\h+)?((?!\2)(use_uid\b|group=\H+\b))\h+(?:[^#\n\r]+\h+)?((?!\1)(use_uid\b|group=\H+\b))(\h+.*)?$' /etc/pam.d/su + if ($test1 -match 'auth required pam_wheel.so use_uid group=') { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.4.1" + Task = "Ensure password creation requirements are configured" + Test = { + $test1 = grep '^\s*minlen\s*' /etc/security/pwquality.confsu + if ($test1 -match 'minlen = 14') { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.4.4" + Task = "Ensure password hashing algorithm is up to date with the latest standards" + Test = { + $test1 = grep -i "^\s*ENCRYPT_METHOD\s*yescrypt\s*$" /etc/login.defs + if ($test1 -match 'ENCRYPT_METHOD yescrypt') { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.4.5" + Task = "Ensure all current passwords uses the configured hashing algorithm" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-5.4.5.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.1.1" + Task = "Ensure minimum days between password changes is configured" + Test = { + $test1 = grep -E '^[[:space:]]*PASS_MIN_DAYS[[:space:]]+' /etc/login.defs | grep -v '^#' + if ($test1 -ge 1) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.1.2" + Task = "Ensure password expiration is 365 days or less" + Test = { + $test1 = awk '/^PASS_MAX_DAYS/ && $2 <= 365 {print "true"; exit}' /etc/login.defs + $test2 = awk -F: '(/^[^:]+:[^!*]/ && ($5>365 || $5~/([0-1]|-1|\s*)/)){print $1 " " $5}' /etc/shadow + if ($test1 -match 'true' -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.1.3" + Task = "Ensure password expiration warning days is 7 or more" + Test = { + $test1 = grep PASS_WARN_AGE /etc/login.defs | cut -d ' ' -f2 + if ($test1 -ge 7) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.1.4" + Task = "Ensure inactive password lock is 30 days or less" + Test = { + $test1 = useradd -D | grep INACTIVE | cut -d '=' -f2 + if ($test1 -le 30) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.1.5" + Task = "Ensure all users last password change date is in the past" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/CIS-Ubuntu22.04_LTS-5.5.1.5.sh" + $result = bash $path + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.2" + Task = "Ensure system accounts are secured" + Test = { + $test1 = awk -F: '$1!~/(root|sync|shutdown|halt|^\+)/ && $3<'"$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)"' && $7!~/((\/usr)?\/sbin\/nologin)/ && $7!~/(\/bin)?\/false/ {print}' /etc/passwd + $test2 = awk -F: '($1!~/(root|^\+)/ && $3<'"$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)"') {print $1}' /etc/passwd | xargs -I '{}' passwd -S '{}' | awk '($2!~/LK?/) {print $1}' + if ($test1 -eq $null -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.3" + Task = "Ensure default group for the root account is GID 0" + Test = { + $test1 = grep "^root:" /etc/passwd | cut -f4 -d ':' + if ($test1 -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.4" + Task = "Ensure default user umask is 027 or more restrictive" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/CIS-Ubuntu22.04_LTS-5.5.4.sh" + $result = bash $path + $test2 = grep -RPi '(^|^[^#]*)\s*umask\s+([0-7][0-7][01][0-7]\b|[0-7][0-7][0-7][0-6]\b|[0-7][01][0-7]\b|[0-7][0-7][0-6]\b|(u=[rwx]{0,3},)?(g=[rwx]{0,3},)?o=[rwx]+\b|(u=[rwx]{1,3},)?g=[^rx]{1,3}(,o=[rwx]{0,3})?\b)' /etc/login.defs /etc/profile* /etc/bash.bashrc* + if ($result -match "Default user umask is set" -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.5" + Task = "Ensure default user shell timeout is 900 seconds or less" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.5.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.1" + Task = "Ensure permissions on /etc/passwd are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/passwd + if ($test1 -match "/etc/passwd\s+644\s+0/root\s+0/root") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.2" + Task = "Ensure permissions on /etc/passwd- are configured" + Test = { + $test1 = stat /etc/passwd- + if ($test1 -eq "Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.3" + Task = "Ensure permissions on /etc/group are configured" + Test = { + $test1 = stat /etc/group + if ($test1 -eq "Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.4" + Task = "Ensure permissions on /etc/group- are configured" + Test = { + $test1 = stat /etc/group- | grep 0644 + if ($test1 -eq "Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.5" + Task = "Ensure permissions on /etc/shadow are configured" + Test = { + $test1 = stat /etc/shadow | grep 0640 + if ($test1 -eq "Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 0/ root)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.6" + Task = "Ensure permissions on /etc/shadow- are configured" + Test = { + $test1 = stat /etc/shadow- | grep 0640 + if ($test1 -eq "Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 42/ shadow)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.7" + Task = "Ensure permissions on /etc/gshadow are configured" + Test = { + $test1 = stat /etc/gshadow | grep 0640 + if ($test1 -eq "Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 42/ shadow)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.8" + Task = "Ensure permissions on /etc/gshadow- are configured" + Test = { + $test1 = stat /etc/gshadow- | grep 0640 + if ($test1 -eq "Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 42/ shadow)") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.9" + Task = "Ensure no world writable files exist" + Test = { + #$partitions = mapfile -t partitions < (sudo fdisk -l | grep -o '/dev/[^ ]*') + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -0002 + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.10" + Task = "Ensure no unowned files or directories exist" + Test = { + $command = @' +df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -nouser +'@ + $test1 = bash -c $command + + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.11" + Task = "Ensure no ungrouped files or directories exist" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nogroup + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.12" + Task = "Audit SUID executables" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -4000 + $message = "" + foreach ($line in $test1) { + $message += "
$line" + } + return @{ + Message = "Please review following list of files: $($message)" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "6.1.13" + Task = "Audit SGID executables" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -2000 + $message = "" + foreach ($line in $test1) { + $message += "
$line" + } + return @{ + Message = "Please review following list of files: $($message)" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "6.2.1" + Task = "Ensure accounts in /etc/passwd use shadowed passwords" + Test = { + $test1 = awk -F: '($2 != "x" ) { print $1 " is not set to shadowed passwords "}' /etc/passwd + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.2" + Task = "Ensure /etc/shadow password fields are not empty" + Test = { + $test1 = awk -F: '($2 == "" ) { print $1 " does not have a password "}' /etc/shadow + if ($test1 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.3" + Task = "Ensure all groups in /etc/passwd exist in /etc/group" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.3.sh" + $result = bash $path + $status = $? + + if ($status -match "True") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.4" + Task = "Ensure shadow group is empty" + Test = { + $test1 = awk -F: '($1=="shadow") {print $NF}' /etc/group + $test2 = awk -F: -v GID="$(awk -F: '($1=="shadow") {print $3}' /etc/group)" '($4==GID) {print $1}' /etc/passwd + if ($test1.Length -eq 0 -and $test2 -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.5" + Task = "Ensure no duplicate UIDs exist" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.5.sh" + $result = bash $path + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.6" + Task = "Ensure no duplicate GIDs exist" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.6.sh" + $result = bash $path + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.7" + Task = "Ensure no duplicate user names exist" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.7.sh" + $result = bash $path + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.8" + Task = "Ensure no duplicate group names exist" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.8.sh" + $result = bash $path + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.9" + Task = "Ensure root PATH Integrity" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.9.sh" + $result = bash $path + if ($result -eq $null) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.10" + Task = "Ensure root is the only UID 0 account" + Test = { + $test1 = awk -F: '($3 == 0) { print $1 }' /etc/passwd + if ($test1 -eq "root") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.11" + Task = "Ensure local interactive user home directories exist" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.11.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.12" + Task = "Ensure local interactive users own their home directories" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.12.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.13" + Task = "Ensure local interactive user home directories are mode 750 or more restrictive" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.13.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.14" + Task = "Ensure no local interactive user has .netrc files" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.14.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.15" + Task = "Ensure no local interactive user has .forward files" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.15.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.16" + Task = "Ensure no local interactive user has .rhosts files" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.16.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.17" + Task = "Ensure local interactive user dot files are not group or world writable" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath + "/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.17.sh" + $result = bash $path + foreach ($line in $result) { + if (!($line -match "PASS")) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} \ No newline at end of file diff --git a/ATAPAuditor/AuditGroups/Debian Linux 12-CIS-1.0.1.ps1 b/ATAPAuditor/AuditGroups/Debian Linux 12-CIS-1.0.1.ps1 new file mode 100644 index 0000000..bbb1770 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Debian Linux 12-CIS-1.0.1.ps1 @@ -0,0 +1,4115 @@ +$rcTrue = "True" +$rcCompliant = "Compliant" +$rcFalse = "False" +$rcNone = "None" +$rcNonCompliant = "Non-Compliant" +$rcNonCompliantManualReviewRequired = "Manual review required" +$rcCompliantIPv6isDisabled = "IPv6 is disabled" +$rcFirewallStatus1 = "Using nftables" +$rcFirewallStatus2 = "Using ufw" +$rcFirewallStatus3 = "Using iptables" + +$retCompliant = @{ + Message = $rcCompliant + Status = $rcTrue +} +$retNonCompliant = @{ + Message = $rcNonCompliant + Status = $rcFalse +} +$retCompliantIPv6Disabled = @{ + Message = $rcCompliantIPv6isDisabled + Status = $rcTrue +} +$retNonCompliantManualReviewRequired = @{ + Message = $rcNonCompliantManualReviewRequired + Status = $rcNone +} +$retUsingFW1 = @{ + Message = $rcFirewallStatus1 + Status = $rcNone +} +$retUsingFW2 = @{ + Message = $rcFirewallStatus2 + Status = $rcNone +} +$retUsingFW3 = @{ + Message = $rcFirewallStatus3 + Status = $rcNone +} + +# Firewall evaluation +function GetFirewallStatus { + # 0 - undefined + # 1 - using nftables + # 2 - using ufw + # 3 - using iptables + + $t_UFW = dpkg-query -f='${db:Status-Abbrev}' -W ufw 2>/dev/null + $t_NFT = dpkg-query -f='${db:Status-Abbrev}' -W nftables 2>/dev/null + $t_IPT = dpkg-query -f='${db:Status-Abbrev}' -W iptables 2>/dev/null + $t_UFW_en = systemctl is-enabled ufw 2>/dev/null + if ($t_UFW -match "ii"){ + $t_UFW_inac = ufw status 2>/dev/null | grep -iE "Status: Ina[ck]tive?" + $t_UFW_ac = ufw status 2>/dev/null | grep -iE "Status: A[ck]tive?" + } else { + $t_UFW_ac = $null + $t_UFW_inac = $null + } + $t_NFT_en = systemctl is-enabled nftables.service 2>/dev/null + + # Testing 1 - nftable installed, ufw not or inactive + if ($t_NFT -match "ii" -and $t_IPT -match "^(rc |un |)$" -and ($t_UFW -match "^(rc |un |)$" -or $t_UFW_inac -ne $null) -and $t_NFT_en -match "enabled"){ + return 1 + } + + # Testing 2 - ufw, iptables installed, nftables not + if ( $t_UFW -match "ii" -and $t_UFW_ac -ne $null -and $t_UFW_en -match "enabled" -and $t_IPT -match "ii" -and $t_NFT -match "^(rc |un |)$"){ + return 2 + } + + # Testing 3 - only iptables + if ($t_NFT -match "^(rc |un |)$" -and $t_UFW -match "^(rc |un |)$" -and $t_IPT -match "ii"){ + return 3 + } + + return 0 +} + +$FirewallStatus = GetFirewallStatus + +$parentPath = Split-Path -Parent -Path $PSScriptRoot +$scriptPath = $parentPath + "/Helpers/ShellScripts/Ubuntu22.04_Debian12/" +$commonPath = $parentPath + "/Helpers/ShellScripts/common/" + +[AuditTest] @{ + Id = "1.1.1.1" + Task = "Ensure cramfs kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.2" + Task = "Ensure freevxfs kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.3" + Task = "Ensure hfs kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.4" + Task = "Ensure hfsplus kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.5" + Task = "Ensure jffs2 kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.6" + Task = "Ensure squashfs kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.7" + Task = "Ensure udf kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.8" + Task = "Ensure usb-storage kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.1.1" + Task = "Ensure /tmp is a separate partition" + Test = { + $result = findmnt --kernel /tmp + if($result -match "/tmp"){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.1.2.1.2" + Task = "Ensure nodev option set on /tmp partition" + Test = { + $script = $commonPath + "1.1.2.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.1.3" + Task = "Ensure nosuid option set on /tmp partition" + Test = { + $script = $commonPath + "1.1.2.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.1.4" + Task = "Ensure noexec option set on /tmp partition" + Test = { + $result = findmnt --kernel /tmp | grep noexec + if($result -match "noexec"){ + return $retCompliant + } + + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "1.1.2.2.1" + Task = "Ensure /dev/shm is a separate partition" + Test = { + $script = $scriptPath + "1.1.2.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.2.2.2" + Task = "Ensure nodev option set on /dev/shm partition" + Test = { + $script = $commonPath + "1.1.2.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.2.3" + Task = "Ensure nosuid option set on /dev/shm partition" + Test = { + $script = $commonPath + "1.1.2.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.2.4" + Task = "Ensure noexec option set on /dev/shm partition" + Test = { + $script = $commonPath + "1.1.2.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.3.1" + Task = "Ensure separate partition exists for /home" + Test = { + $result = findmnt --kernel /home + if($result -match "/home"){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.1.2.3.2" + Task = "Ensure nodev option set on /home partition" + Test = { + $script = $commonPath + "1.1.2.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.3.3" + Task = "Ensure nosuid option set on /home partition" + Test = { + $script = $commonPath + "1.1.2.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.4.1" + Task = "Ensure separate partition exists for /var" + Test = { + $result = findmnt --kernel /var + if($result -match !$null){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.1.2.4.2" + Task = "Ensure nodev option set on /var partition" + Test = { + $script = $commonPath + "1.1.2.4.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.4.3" + Task = "Ensure nosuid option set on /var partition" + Test = { + $script = $commonPath + "1.1.2.4.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.5.1" + Task = "Ensure separate partition exists for /var/tmp" + Test = { + $result = findmnt --kernel /var/tmp + if($result -match "/var/tmp"){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.1.2.5.2" + Task = "Ensure nodev option set on /var/tmp partition" + Test = { + $script = $commonPath + "1.1.2.5.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.5.3" + Task = "Ensure nosuid option set on /var/tmp partition" + Test = { + $script = $commonPath + "1.1.2.5.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.5.4" + Task = "Ensure noexec option set on /var/tmp partition" + Test = { + $script = $commonPath + "1.1.2.5.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.6.1" + Task = "Ensure separate partition exists for /var/log" + Test = { + $result = findmnt --kernel /var/log + if($result -match !$null){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.1.2.6.2" + Task = "Ensure nodev option set on /var/log partition" + Test = { + $script = $commonPath + "1.1.2.6.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.6.3" + Task = "Ensure nosuid option set on /var/log partition" + Test = { + $script = $commonPath + "1.1.2.6.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.6.4" + Task = "Ensure noexec option set on /var/log partition" + Test = { + $script = $commonPath + "1.1.2.6.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.7.1" + Task = "Ensure separate partition exists for /var/log/audit" + Test = { + $result = findmnt --kernel /var/log/audit + if($result -match "/var/log/audit"){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.1.2.7.2" + Task = "Ensure nodev option set on /var/log/audit partition" + Test = { + $script = $commonPath + "1.1.2.7.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.7.3" + Task = "Ensure nosuid option set on /var/log/audit partition" + Test = { + $script = $commonPath + "1.1.2.7.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.7.4" + Task = "Ensure noexec option set on /var/log/audit partition" + Test = { + $script = $commonPath + "1.1.2.7.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.2.1.1" + Task = "Ensure GPG keys are configured" + Test = { + $result = apt-key list + if($result -ne $null){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.2.1.2" + Task = "Ensure package manager repositories are configured" + Test = { + $result = apt-cache policy + if($result -ne $null){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.2.2.1" + Task = "Ensure updates, patches, and additional security software are installed" + Test = { + $output = apt -s upgrade + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.3.1.1" + Task = "Ensure AppArmor is installed" + Test = { + $result = dpkg-query -W -f='${db:Status-Abbrev}' apparmor 2>/dev/null + + if($result -match "ii"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.3.1.2" + Task = "Ensure AppArmor is enabled in the bootloader configuration" + Test = { + $script = $scriptPath + "1.3.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.3.1.3" + Task = "Ensure all AppArmor Profiles are in enforce or complain mode" + Test = { + $profileMode1 = apparmor_status | grep profiles | sed '1!d' | cut -d ' ' -f 1 + $profileMode2 = apparmor_status | grep profiles | sed '2!d' | cut -d ' ' -f 1 + $profileMode3 = apparmor_status | grep profiles | sed '3!d' | cut -d ' ' -f 1 + $result = expr $profileMode3 + $profileMode2 + + $unconfinedProcesses = apparmor_status | grep processes | sed '4!d' | cut -d ' ' -f 1 + + if($result -eq $profileMode1 -and $unconfinedProcesses -eq 0){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.3.1.4" + Task = "Ensure all AppArmor Profiles are enforcing" + Test = { + $script = $scriptPath + "1.3.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.4.1" + Task = "Ensure bootloader password is set" + Test = { + $result1 = grep "^set superusers" /boot/grub/grub.cfg + $result2 = grep "^password" /boot/grub/grub.cfg + if($result1 -match "set superusers=" -and $result2 -match "password_pbkdf2"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.4.2" + Task = "Ensure access to bootloader config is configured" + Test = { + $script = $commonPath + "1.4.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.5.1" + Task = "Ensure address space layout randomization is enabled" + Test = { + $script = $commonPath + "1.5.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.5.2" + Task = "Ensure ptrace_scope is restricted" + Test = { + $script = $commonPath + "1.5.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.5.3" + Task = "Ensure core dumps are restricted" + Test = { + $script = $scriptPath + "1.5.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.5.4" + Task = "Ensure prelink is not installed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W prelink 2>/dev/null + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "1.5.5" + Task = "Ensure Automatic Error Reporting is not enabled" + Test = { + $result1 = dpkg-query -s apport > /dev/null 2>&1 && grep -Psi -- '^\h*enabled\h*=\h*[^0]\b' /etc/default/apport + $result2 = systemctl is-active apport.service | grep '^active' + if($result1 -eq $null -and $result2 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.6.1" + Task = "Ensure message of the day is configured properly" + Test = { + $script = $scriptPath + "1.6.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.6.2" + Task = "Ensure local login warning banner is configured properly" + Test = { + $output1 = cat /etc/issue + + if($output1 -eq $null){ + return $retCompliant + } + + $output2 = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue + + if($output1 -ne $null -and $output2 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.6.3" + Task = "Ensure remote login warning banner is configured properly" + Test = { + $output1 = cat /etc/issue.net + + if($output1 -eq $null){ + return $retCompliant + } + + $output2 = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue.net + + if($output1 -ne $null -and $output2 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.6.4" + Task = "Ensure access to /etc/motd is configured" + Test = { + $script = $scriptPath + "1.6.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.6.5" + Task = "Ensure access to /etc/issue is configured" + Test = { + $output = stat -c '%#a' /etc/issue | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.6.6" + Task = "Ensure access to /etc/issue.net is configured" + Test = { + $output = stat -c '%#a' /etc/issue.net | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.1" + Task = "Ensure GDM is removed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W gdm3 2>/dev/null + if($test1 -match "^(rc |un |)$"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.2" + Task = "Ensure GDM login banner is configured" + Test = { + $path = $scriptPath + "1.8.2.sh" + $result=bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.3" + Task = "Ensure GDM disable-user-list option is enabled" + Test = { + $path = $scriptPath + "1.8.3.sh" + $result=bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.4" + Task = "Ensure GDM screen locks when the user is idle" + Test = { + $path = $scriptPath + "1.8.4.sh" + $result=bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.5" + Task = "Ensure GDM screen locks cannot be overridden" + Test = { + $path = $scriptPath + "1.8.5.sh" + $result=bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.6" + Task = "Ensure GDM automatic mounting of removable media is disabled" + Test = { + $path = $scriptPath + "1.8.6.sh" + $result=bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.7" + Task = "Ensure GDM disabling automatic mounting of removable media is not overridden" + Test = { + $path = $scriptPath + "1.8.7.sh" + $result=bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.8" + Task = "Ensure GDM autorun-never is enabled" + Test = { + $path = $scriptPath + "1.8.8.sh" + $result=bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.9" + Task = "Ensure GDM autorun-never is not overridden" + Test = { + $path = $scriptPath + "1.8.9.sh" + $result=bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.10" + Task = "Ensure XDCMP is not enabled" + Test = { + $script = $scriptPath + "1.7.10.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "2.1.1" + Task = "Ensure autofs services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null autofs + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null autofs.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.2" + Task = "Ensure avahi daemon services are not in use" + Test = { + $status = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null avahi-daemon + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null avahi-daemon.socket + if(! $?){ + $test3 = systemctl is-enabled 2>/dev/null avahi-daemon.service + if(! $?){ + return $retCompliant + } + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.3" + Task = "Ensure dhcp server services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null isc-dhcp-server + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null isc-dhcp-server.service + if(! $?){ + $test2 = systemctl is-enabled 2>/dev/null isc-dhcp-server6.service + if(! $?){ + return $retCompliant + } + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.4" + Task = "Ensure dns server services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null bind9 + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null bind9.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.5" + Task = "Ensure dnsmasq server services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null dnsmasq + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null dnsmasq.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.6" + Task = "Ensure ftp server services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null vsftpd + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null vsftpd.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.7" + Task = "Ensure ldap server services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null slapd + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null slapd.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.8" + Task = "Ensure message access server services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null dovecot-imapd + $test2 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null dovecot-pop3d + if("$test1" -match "^(rc |un |)$" -and "$test2" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test3 = systemctl is-enabled 2>/dev/null dovecot.socket + if(! $?){ + $test4 = systemctl is-enabled 2>/dev/null dovecot.service + if(! $?){ + return $retCompliant + } + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.9" + Task = "Ensure network file system services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null nfs-kernel-server + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null nfs-kernel.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.10" + Task = "Ensure nis server services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null ypserv + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null ypserv.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.11" + Task = "Ensure print server services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null cups + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null cups.service + if(! $?){ + $test3 = systemctl is-enabled 2>/dev/null cups.socket + if(! $?){ + return $retCompliant + } + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.12" + Task = "Ensure rpcbind services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null rpcbind + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null rpcbind.service + if(! $?){ + $test3 = systemctl is-enabled 2>/dev/null rpcbind.socket + if(! $?){ + return $retCompliant + } + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.13" + Task = "Ensure rsync services are not in use" + Test = { + $script = $commonPath + "2.1.13.sh" + bash $script + if ($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.14" + Task = "Ensure samba file server services are not in use" + Test = { + $test1 = dpkg-query -W -f='${db:Status-Abbrev}' samba 2>/dev/null + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null samba.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.15" + Task = "Ensure snmp services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null snmpd + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null snmpd.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.16" + Task = "Ensure tftp server services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null tftpd-hpa + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null tftpd-hpa.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.17" + Task = "Ensure web proxy server services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null squid + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null squid.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.18" + Task = "Ensure web server services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null apache2 + $test2 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null ginx + if("$test1" -match "^(rc |un |)$" -and "$test2" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $services = 'apache2.service', 'apache2.socket', 'nginx.service', 'nginx.socket' + $test3 = "disabled" + foreach ($service in $services){ + $test4 = systemctl is-enabled $service 2>/dev/null + if($?){ + $test3 = "enabled" + } + } + if($test3 -match "disabled"){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.19" + Task = "Ensure xinetd services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null xinetd + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null xinetd.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.20" + Task = "Ensure X window server services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null xserver-commen + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.21" + Task = "Ensure mail transfer agent is configured for local-only mode" + Test = { + $test1 = ss -lntu | grep -E ':25\s' | grep -E -v '\s(127.0.0.1|::1):25\s' + if($test1 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.22" + Task = "Ensure only approved services are listening on a network interface" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "2.2.1" + Task = "Ensure NIS Client is not installed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W nis 2>/dev/null + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "Ensure rsh client is not installed" + Test = { + $status = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null rsh-client + if($status -match "^(rc |un |)$"){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.2.3" + Task = "Ensure talk client is not installed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null talk + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.2.4" + Task = "Ensure telnet client Server is not installed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W telnet 2>/dev/null + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.2.5" + Task = "Ensure ldap client is not installed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W lapd-utils 2>/dev/null + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.2.6" + Task = "Ensure ftp client is not installed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W ftp 2>/dev/null + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.3.1.1" + Task = "Ensure a single time synchronization daemon is in use" + Test = { + $path = $scriptPath + "2.1.1.1.sh" + $result=bash $path + if($result -match "PASS:"){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.3.2.1" + Task = "Ensure systemd-timesyncd configured with authorized timeserver" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "2.3.2.2" + Task = "Ensure systemd-timesyncd is enabled and running" + Test = { + $test1 = systemctl is-enabled systemd-timesyncd.service + $time = timedatectl status + if($test1 -match "enabled" -and $time -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.3.3.1" + Task = "Ensure chrony is configured with authorized timeserver" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "2.3.3.2" + Task = "Ensure chrony is running as user _chrony" + Test = { + $script = $scriptPath + "2.3.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "2.3.3.3" + Task = "Ensure chrony is enabled and running" + Test = { + $test1 = $(systemctl is-enabled cron.service 1>/dev/null 2>/dev/null; echo $?) + $test2 = $(systemctl is-active cron.service 1>/dev/null 2>/dev/null; echo $?) + if($test1 -and $test2 ){ + return $retCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.1" + Task = "Ensure cron daemon is enabled and active" + Test = { + $test1 = systemctl is-enabled cron + $test2 = systemctl status cron | grep 'Active: active (running) ' + if($test1 -eq "enabled" -and $test2 -match "running"){ + return $retCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.2" + Task = "Ensure permissions on /etc/crontab are configured" + Test = { + $test1 = stat -c '%#a' /etc/crontab | grep -q "0600" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.3" + Task = "Ensure permissions on /etc/cron.hourly are configured" + Test = { + $test1 = stat -c '%#a' /etc/cron.hourly/ | grep -q 0700 + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.4" + Task = "Ensure permissions on /etc/cron.daily are configured" + Test = { + $test1 = stat -c '%#a' /etc/cron.daily/ | grep -q "0700" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.5" + Task = "Ensure permissions on /etc/cron.weekly are configured" + Test = { + $test1 = stat -c '%#a' /etc/cron.weekly/ | grep -q "0700" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.6" + Task = "Ensure permissions on /etc/cron.monthly are configured" + Test = { + $test1 = stat -c '%#a' /etc/cron.monthly/ | grep -q "0700" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.7" + Task = "Ensure permissions on /etc/cron.d are configured" + Test = { + $test1 = stat -c '%#a' /etc/cron.d/ | grep -q "0700" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.8" + Task = "Ensure crontab is restricted to authorized users" + Test = { + $script = $commonPath + "2.4.1.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "2.4.2.1" + Task = "Ensure at is restricted to authorized users" + Test = { + $script = $commonPath + "2.4.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.1.1" + Task = "Ensure IPv6 status is identified" + Test = { + $path = $scriptPath + "3.1.1.sh" + $result=bash $path + if($result -match "IPv6 is enabled on the system"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.1.2" + Task = "Ensure wireless interfaces are disabled" + Test = { + $script = $commonPath + "3.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.1.3" + Task = "Ensure bluetooth services are not in use" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null bluez + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null bluetooth.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "3.2.1" + Task = "Ensure dccp kernel module is not available" + Test = { + $script = $commonPath + "3.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.2.2" + Task = "Ensure tipc kernel module is not available" + Test = { + $script = $commonPath + "3.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.2.3" + Task = "Ensure rds kernel module is not available" + Test = { + $script = $commonPath + "3.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.2.4" + Task = "Ensure sctp kernel module is not available" + Test = { + $script = $commonPath + "3.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.1" + Task = "Ensure ip forwarding is disabled" + Test = { + $script = $commonPath + "3.3.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.2" + Task = "Ensure packet redirect sending is disabled" + Test = { + $script = $commonPath + "3.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.3" + Task = "Ensure bogus icmp responses are ignored" + Test = { + $script = $commonPath + "3.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.4" + Task = "Ensure broadcast icmp requests are ignored" + Test = { + $script = $commonPath + "3.3.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.5" + Task = "Ensure icmp redirects are not accepted" + Test = { + $script = $commonPath + "3.3.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.6" + Task = "Ensure secure icmp redirects are not accepted" + Test = { + $script = $commonPath + "3.3.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.7" + Task = "Ensure reverse path filtering is enabled" + Test = { + $script = $commonPath + "3.3.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.8" + Task = "Ensure source routed packets are not accepted" + Test = { + $script = $commonPath + "3.3.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.9" + Task = "Ensure suspicious packets are logged" + Test = { + $script = $commonPath + "3.3.9.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.10" + Task = "Ensure tcp syn cookies is enabled" + Test = { + $script = $commonPath + "3.3.10.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.11" + Task = "Ensure ipv6 router advertisements are not accepted" + Test = { + $script = $commonPath + "3.3.11.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "4.1.1" + Task = "Ensure ufw is installed" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W ufw 2>/dev/null + if($test1 -match "ii"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.1.2" + Task = "Ensure iptables-persistent is not installed with ufw" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null iptables-persistent + if("$test1" -match "^(rc |un |)$"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.1.3" + Task = "Ensure ufw service is enabled" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = systemctl is-enabled ufw 2>/dev/null + $test2 = systemctl is-active ufw 2>/dev/null + if($test1 -match "enabled" -and $test2 -match "active"){ + $test3 = ufw status | grep -iE "Status: A[ck]tive?" + if($test3 -ne $null){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.1.4" + Task = "Ensure ufw loopback traffic is configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = dpkg-query -W -f='${db:Status-Abbrev}' ufw + if($test1 -match "ii"){ + $test2 = ufw status verbose | grep -iE "Status: A[ck]tive?" + if($test2 -eq $null){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.1.5" + Task = "Ensure ufw outbound connections are configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = dpkg-query -W -f='${db:Status-Abbrev}' ufw + if($test1 -match "ii"){ + $test2 = ufw status numbered | grep -iE "Status: Ina[ck]tive?" + if($test2 -eq $null){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.1.6" + Task = "Ensure ufw firewall rules exist for all open ports" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $path = $scriptPath + "3.5.1.6.sh" + $result=bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.1.7" + Task = "Ensure ufw default deny firewall policy" + Test = { + $test1 = dpkg-query -W -f='${db:Status-Abbrev}' ufw + if($test1 -match "ii"){ + $test2 = ufw status verbose | grep -iE "allow" + if($test2 -eq $null){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.2.1" + Task = "Ensure nftables is installed" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W nftables 2>/dev/null + if($test1 -match "ii"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.2.2" + Task = "Ensure ufw is uninstalled or disabled with nftables" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W ufw 2>/dev/null + if($test1 -match "^(rc |un |)$"){ + return $retCompliant + } else { + $test2 = ufw status | grep -iE "Status: Ina[ck]tive?" + if($test2 -ne $null) { + return $retCompliant + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "4.2.3" + Task = "Ensure iptables are flushed with nftables" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $script = $scriptPath + "4.2.3.sh" + $result = bash $script + if ($?) { + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.2.4" + Task = "Ensure a nftables table exists" + Test = { + try{ + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = nft list tables + if($test1 -match "table"){ + return $retCompliant + } + return $retNonCompliant + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.2.5" + Task = "Ensure nftables base chains exist" + Test = { + try{ + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = nft list ruleset | grep 'hook input' + $test2 = nft list ruleset | grep 'hook forward' + $test3 = nft list ruleset | grep 'hook output' + if($test1 -match "type filter hook input" -and $test2 -match "type filter hook forward" -and $test3 -match "type filter hook output"){ + return $retCompliant + } + return $retNonCompliant + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.2.6" + Task = "Ensure nftables loopback traffic is configured" + Test = { + try{ + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + if($isIPv6Disabled -ne $true){ + $test1 = nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept' + $test2 = nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr' + if($test1 -match 'iif "lo" accept' -and $test2 -match "ip saddr 127.0.0.0/8 counter packets 0 bytes 0 drop"){ + return $retCompliant + } + } + else{ + $test = nft list ruleset | awk '/hook input/,/}/' | grep 'ip6 saddr' + if($test -match 'ip6 saddr ::1 counter packets 0 bytes 0 drop'){ + return $retCompliant + } + } + return $retNonCompliant + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.2.7" + Task = "Ensure nftables outbound and established connections are configured" + Test = { + try{ + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = nft list ruleset | awk '/hook input/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + $test2 = nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + if($test1 -match "ip protocol tcp ct state established accept" -and $test1 -match "p protocol udp ct state established accept" -and $test1 -match "ip protocol icmp ct state established accept" -and $test2 -match "ip protocol tcp ct state established,related,new accep" -and $test2 -match "ip protocol udp ct state established,related,new accept" -and $test2 -match "ip protocol icmp ct state established,related,new accept"){ + return $retCompliant + } + return $retNonCompliant + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.2.8" + Task = "Ensure nftables default deny firewall policy" + Test = { + try{ + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = nft list ruleset | grep 'hook input' + $test2 = nft list ruleset | grep 'hook forward' + $test3 = nft list ruleset | grep 'hook output' + if($test1 -match "policy drop" -and $test2 -match "policy drop" -and $test3 -match "policy drop"){ + return $retCompliant + } + return $retNonCompliant + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.2.9" + Task = "Ensure nftables service is enabled" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = systemctl is-enabled nftables + if($test1 -match "enabled"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.2.10" + Task = "Ensure nftables rules are permanent" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $path1 = $scriptPath + "3.5.2.10_1.sh" + $path2 = $scriptPath + "3.5.2.10_2.sh" + $path3 = $scriptPath + "3.5.2.10_3.sh" + if($path1 -ne $null -and $path2 -ne $null -and $path3 -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.3.1.1" + Task = "Ensure iptables packages are installed" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null iptables-persistent + if($test1 -match "ii"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.3.1.2" + Task = "Ensure nftables is not installed with iptables" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null nftables + if("$test1" -match "^(rc |un |)$"){ + return $retNonCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "4.3.1.3" + Task = "Ensure ufw is uninstalled or disabled with iptables" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W ufw 2>/dev/null + if($test1 -match "^(rc |un |)$"){ + return $retCompliant + } else { + $test2 = ufw status | grep -iE "Status: Ina[ck]tive?" + $test3 = systemctl is-enabled ufw + if($test2 -ne $null -and $test3 -match "masked") { + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.3.2.1" + Task = "Ensure iptables default deny firewall policy" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $output = iptables -L + $test1 = $output -match "DROP" | grep "Chain INPUT (policy DROP)" + $test2 = $output -match "DROP" | grep "Chain FORWARD (policy DROP)" + $test3 = $output -match "DROP" | grep "Chain OUTPUT (policy DROP)" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.3.2.2" + Task = "Ensure iptables loopback traffic is configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $test1 = iptables -L INPUT -v -n | grep "Chain\s*INPUT\s*(policy\s*DROP" + $test2 = iptables -L OUTPUT -v -n | grep "Chain\s*OUTPUT\s*(policy\s*DROP" + if($test1 -ne $null -and $test2 -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.3.2.3" + Task = "Ensure iptables outbound and established connections are configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $test1 = iptables -L -v -n + if($test1 -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} +# 3.5.3.2.4 ... + +[AuditTest] @{ # in CIS it's automated, but in Excelsheet it's manual + Id = "4.3.2.4" + Task = "Ensure iptables firewall rules exist for all open ports" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "4.3.3.1" + Task = "Ensure ip6tables default deny firewall policy" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $output = ip6tables -L + $test11 = $output -match "DROP" | grep "Chain INPUT (policy DROP)" + $test12 = $output -match "REJECT" | grep "Chain INPUT (policy REJECT)" + $test21 = $output -match "DROP" | grep "Chain OUTPUT (policy DROP)" + $test22 = $output -match "REJECT" | grep "Chain OUTPUT (policy REJECT)" + $test31 = $output -match "DROP" | grep "Chain FORWARD (policy DROP)" + $test32 = $output -match "REJECT" | grep "Chain FORWARD (policy REJECT)" + + if ($IPv6Status -eq $false) { + return @{ + Message = "IPv6 is disabled" + Status = "True" + } + } + if(($test11 -ne $null -or $test12 -ne $null) -and ($test21 -ne $null -or $test22 -ne $null) -and ($test31 -ne $null -or $test32 -ne $null)){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.3.3.2" + Task = "Ensure ip6tables loopback traffic is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "4.3.3.3" + Task = "Ensure ip6tables outbound and established connections are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "4.3.3.4" + Task = "Ensure ip6tables firewall rules exist for all open ports" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "5.1.1" + Task = "Ensure cron daemon is enabled and running" + Test = { + $test1 = systemctl is-enabled cron + $test2 = systemctl status cron | grep 'Active: active (running) ' + if($test1 -eq "enabled" -and $test2 -match "running"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.1.2" + Task = "Ensure permissions on /etc/crontab are configured" + Test = { + $test1 = stat -c '%#a' /etc/crontab | grep -q "0600" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.1.3" + Task = "Ensure permissions on SSH public host key files are configured" + Test = { + $script = $commonPath + "5.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.4" + Task = "Ensure sshd access is configured" + Test = { + if (sshd -T | grep -Piq -- "^\h*(allow|deny)(users|groups)\h+\H+") { + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.1.5" + Task = "Ensure sshd Banner is configured" + Test = { + if (sshd -T | grep -Piq -- "^\h*banner\h+\H+") { + return $retCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "5.1.6" + Task = "Ensure sshd Ciphers are configured" + Test = { + $script = $scriptPath + "5.1.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.7" + Task = "Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured" + Test = { + $script = $scriptPath + "5.1.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.8" + Task = "Ensure sshd DisableForwarding is enabled" + Test = { + $script = $scriptPath + "5.1.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.9" + Task = "Ensure sshd GSSAPIAuthentication is disabled" + Test = { + $script = $scriptPath + "5.1.9.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.10" + Task = "Ensure sshd HostbasedAuthentication is disabled" + Test = { + $script = $scriptPath + "5.1.10.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.11" + Task = "Ensure sshd IgnoreRhosts is enabled" + Test = { + $script = $scriptPath + "5.1.11.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.12" + Task = "Ensure sshd KexAlgorithms is configured" + Test = { + $script = $scriptPath + "5.1.12.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.13" + Task = "Ensure sshd LoginGraceTime is configured" + Test = { + $script = $scriptPath + "5.1.13.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.14" + Task = "Ensure sshd LogLevel is configured" + Test = { + $script = $scriptPath + "5.1.14.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.15" + Task = "Ensure sshd MACs are configured" + Test = { + $script = $scriptPath + "5.1.15.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.16" + Task = "Ensure sshd MaxAuthTries is configured" + Test = { + $script = $commonPath + "5.1.16.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.17" + Task = "Ensure sshd MaxSessions is configured" + Test = { + $script = $scriptPath + "5.1.17.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.18" + Task = "Ensure sshd MaxStartups is configured" + Test = { + $script = $scriptPath + "5.1.18.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.19" + Task = "Ensure sshd PermitEmptyPasswords is disabled" + Test = { + $script = $commonPath + "5.1.19.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.20" + Task = "Ensure sshd PermitRootLogin is disabled" + Test = { + $script = $commonPath + "5.1.20.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.21" + Task = "Ensure sshd PermitUserEnvironment is disabled" + Test = { + $script = $commonPath + "5.1.21.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.22" + Task = "Ensure sshd UsePAM is enabled" + Test = { + $script = $commonPath + "5.1.22.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.1" + Task = "Ensure sudo is installed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null sudo + if($test1 -match "ii"){ + return $retNonCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "5.2.2" + Task = "Ensure sudo commands use pty" + Test = { + $script = $commonPath + "5.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.3" + Task = "Ensure sudo log file exists" + Test = { + $script = $commonPath + "5.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.4" + Task = "Ensure users must provide password for privilege escalation" + Test = { + $script = $scriptPath + "5.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.5" + Task = "Ensure re-authentication for privilege escalation is not disabled globally" + Test = { + $script = $scriptPath + "5.2.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.6" + Task = "Ensure sudo authentication timeout is configured correctly" + Test = { + $script = $commonPath + "5.2.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.7" + Task = "Ensure access to the su command is restricted" + Test = { + $script = $scriptPath + "5.2.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.1.1" + Task = "Ensure latest version of pam is installed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null libpam-runtime + if($test1 -match "ii"){ + return $retNonCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "5.3.1.2" + Task = "Ensure libpam-modules is installed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null libpam-modules + if($test1 -match "ii"){ + return $retNonCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "5.3.1.3" + Task = "Ensure libpam-pwquality is installed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null libpam-pwquality + if($test1 -match "ii"){ + return $retNonCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "5.3.2.1" + Task = "Ensure pam_unix module is enabled" + Test = { + $script = $scriptPath + "5.3.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.2.2" + Task = "Ensure pam_faillock module is enabled" + Test = { + $script = $scriptPath + "5.3.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.2.3" + Task = "Ensure pam_pwquality module is enabled" + Test = { + $script = $scriptPath + "5.3.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.2.4" + Task = "Ensure pam_pwhistory module is enabled" + Test = { + $script = $scriptPath + "5.3.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.1.1" + Task = "Ensure password failed attempts lockout is configured" + Test = { + $script = $commonPath + "5.3.3.1.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.1.2" + Task = "Ensure password unlock time is configured" + Test = { + $script = $commonPath + "5.3.3.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.1.3" + Task = "Ensure password failed attempts lockout includes root account" + Test = { + $script = $commonPath + "5.3.3.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.1" + Task = "Ensure password number of changed characters is configured" + Test = { + $script = $commonPath + "5.3.3.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.2" + Task = "Ensure minimum password length is configured" + Test = { + $script = $commonPath + "5.3.3.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.3" + Task = "Ensure password complexity is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "5.3.3.2.4" + Task = "Ensure password same consecutive characters is configured" + Test = { + $script = $commonPath + "5.3.3.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.5" + Task = "Ensure password maximum sequential characters is configured" + Test = { + $script = $commonPath + "5.3.3.2.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.6" + Task = "Ensure password dictionary check is enabled" + Test = { + $script = $commonPath + "5.3.3.2.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.7" + Task = "Ensure password quality checking is enforced" + Test = { + $script = $scriptPath + "5.3.3.2.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.8" + Task = "Ensure password quality is enforced for the root user" + Test = { + $script = $scriptPath + "5.3.3.2.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.3.1" + Task = "Ensure password history remember is configured" + Test = { + $script = $scriptPath + "5.3.3.3.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.3.2" + Task = "Ensure password history is enforced for the root user" + Test = { + $script = $scriptPath + "5.3.3.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.3.3" + Task = "Ensure pam_pwhistory includes use_authtok" + Test = { + $script = $commonPath + "5.3.3.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.4.1" + Task = "Ensure pam_unix does not include nullok" + Test = { + $script = $commonPath + "5.3.3.4.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.4.2" + Task = "Ensure pam_unix does not include remember" + Test = { + $script = $scriptPath + "5.3.3.4.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.4.3" + Task = "Ensure pam_unix includes a strong password hashing algorithm" + Test = { + $script = $scriptPath + "5.3.3.4.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.4.4" + Task = "Ensure pam_unix includes use_authtok" + Test = { + $script = $commonPath + "5.3.3.4.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.1" + Task = "Ensure password expiration is configured" + Test = { + $script = $commonPath + "5.4.1.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.2" + Task = "Ensure minimum password age is configured" + Test = { + $script = $commonPath + "5.4.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.3" + Task = "Ensure password expiration warning days is configured" + Test = { + $script = $commonPath + "5.4.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.4" + Task = "Ensure strong password hashing algorithm is configured" + Test = { + $script = $commonPath + "5.4.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.5" + Task = "Ensure inactive password lock is configured" + Test = { + $script = $commonPath + "5.4.1.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.6" + Task = "Ensure all users last password change date is in the past" + Test = { + $path = $scriptPath + "5.5.1.5.sh" + $result=bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.4.2.1" + Task = "Ensure root is the only UID 0 account" + Test = { + $test1 = awk -F: '($3 == 0) { print $1 }' /etc/passwd + if($test1 -match "root"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.4.2.2" + Task = "Ensure root is the only GID 0 account" + Test = { + $test1 = grep "^root:" /etc/passwd | cut -f4 -d ':' + if($test1 -eq 0){ + return $retCompliant + } + return $retNonCompliant + } + } + [AuditTest] @{ + Id = "5.4.2.3" + Task = "Ensure group root is the only GID 0 group" + Test = { + $script = $commonPath + "5.4.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.2.4" + Task = "Ensure root password is set" + Test = { + $script = $scriptPath + "5.4.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.2.5" + Task = "Ensure root PATH Integrity" + Test = { + $path = $scriptPath + "6.2.9.sh" + $result=bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.4.2.6" + Task = "Ensure root user umask is configured" + Test = { + $script = $commonPath + "5.4.2.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.2.7" + Task = "Ensure system accounts do not have a valid login shell" + Test = { + $script = $commonPath + "5.4.2.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.2.8" + Task = "Ensure accounts without a valid login shell are locked" + Test = { + $script = $commonPath + "5.4.2.8.sh" + bash $script + if ($?) { + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.4.3.1" + Task = "Ensure nologin is not listed in /etc/shells" + Test = { + $script = $commonPath + "5.4.3.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.3.2" + Task = "Ensure default user shell timeout is configured" + Test = { + $script = $commonPath + "5.4.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.3.3" + Task = "Ensure default user umask is configured" + Test = { + $script = $commonPath + "5.4.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.1.1" + Task = "Ensure permissions on /etc/passwd are configured" + Test = { + $test1 = stat -c '%#a' /etc/passwd | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.1.2" + Task = "Ensure permissions on /etc/passwd- are configured" + Test = { + $test1 = stat -c '%#a' /etc/passwd- | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.1.3" + Task = "Ensure cryptographic mechanisms are used to protect the integrity of audit tools" + Test = { + $script = $commonPath + "6.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.1.1.1" + Task = "Ensure journald service is enabled and active" + Test = { + $test1 = systemctl is-enabled rsyslog + if($test1 -match "enabled"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.1.1.2" + Task = "Ensure journald log file access is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "6.2.1.1.3" + Task = "Ensure journald log file rotation is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "6.2.1.1.4" + Task = "Ensure journald ForwardToSyslog is disabled" + Test = { + $script = $scriptPath + "6.2.1.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.1.1.5" + Task = "Ensure journald Storage is configured" + Test = { + $script = $scriptPath + "6.2.1.1.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.1.1.6" + Task = "Ensure journald Compress is configured" + Test = { + $script = $scriptPath + "6.2.1.1.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.1.2.1" + Task = "Ensure systemd-journal-remote is installed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null systemd-journal-remote + if($test1 -match "ii"){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "6.2.1.2.2" + Task = "Ensure systemd-journal-remote authentication is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "6.2.1.2.3" + Task = "Ensure systemd-journal-upload is enabled and active" + Test = { + $test1 = systemctl is-enabled systemd-journal-upload.service + $test2 = systemctl is-active systemd-journal-upload.service + if($test1 -eq "enabled" -and $test2 -match "active"){ + return $retCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "6.2.1.2.4" + Task = "Ensure systemd-journal-remote service is not in use" + Test = { + $script = $scriptPath + "6.2.1.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.2.1" + Task = "Ensure access to all logfiles has been configured" + Test = { + $fileListAll = find /var/log -type f -ls + $fileListFiltered = find /var/log -type f -ls | grep "\-....\-\-\-\-\-" + if($fileListAll.Count -eq $fileListFiltered.Count){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.1.1" + Task = "Ensure auditd packages are installed" + Test = { + $test1 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null auditd + $test2 = dpkg-query -f='${db:Status-Abbrev}' -W 2>/dev/null audispd-plugins + if($test1 -match "ii" -and $test2 -match "ii"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.1.2" + Task = "Ensure auditd service is enabled and active" + Test = { + $test1 = systemctl is-enabled auditd + if($test1 -match "enabled"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.1.3" + Task = "Ensure auditing for processes that start prior to auditd is enabled" + Test = { + $script = $scriptPath + "6.3.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.1.4" + Task = "Ensure audit_backlog_limit is sufficient" + Test = { + $script = $scriptPath + "6.3.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.2.1" + Task = "Ensure audit log storage size is configured" + Test = { + $script = $commonPath + "6.3.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.2.2" + Task = "Ensure audit logs are not automatically deleted" + Test = { + $script = $commonPath + "6.3.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.2.3" + Task = "Ensure system is disabled when audit logs are full" + Test = { + $test1 = grep -Pi -- '^\h*disk_full_action\h*=\h*(halt|single)\b' /etc/audit/auditd.conf + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.2.4" + Task = "Ensure system warns when audit logs are low on space" + Test = { + $test1 = grep -Pi -- '^\h*space_left_action\h*=\h*\w+\b' /etc/audit/auditd.conf | awk '{print $3}' + if($test1 -match "^(email|exec|single|halt)$"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.3.1" + Task = "Ensure changes to system administration scope is collected" + Test = { + $script = $commonPath + "6.3.3.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.2" + Task = "Ensure actions as another user are always logged" + Test = { + $script = $commonPath + "6.3.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.3" + Task = "Ensure events that modify the sudo log file are collected" + Test = { + $script = $commonPath + "6.3.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.4" + Task = "Ensure events that modify date and time information are collected" + Test = { + $script = $commonPath + "6.3.3.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.5" + Task = "Ensure events that modify the system's network environment are collected" + Test = { + $script = $commonPath + "6.3.3.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.6" + Task = "Ensure use of privileged commands are collected" + Test = { + $script = $commonPath + "6.3.3.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.7" + Task = "Ensure unsuccessful file access attempts are collected" + Test = { + $script = $commonPath + "6.3.3.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.8" + Task = "Ensure events that modify user/group information are collected" + Test = { + $script = $commonPath + "6.3.3.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.9" + Task = "Ensure discretionary access control permission modification events are collected" + Test = { + $script = $commonPath + "6.3.3.9.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.10" + Task = "Ensure successful file system mounts are collected" + Test = { + $script = $commonPath + "6.3.3.10.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.11" + Task = "Ensure session initiation information is collected" + Test = { + $path1 = $scriptPath + "4.1.3.11_1.sh" + $result11 = bash $path1 | grep "\-w /var/run/utmp -p wa -k session" + $result12 = bash $path1 | grep "\-w /var/log/wtmp -p wa -k session" + $result13 = bash $path1 | grep "\-w /var/log/btmp -p wa -k session" + $path2 = $scriptPath + "4.1.3.11_2.sh" + $result21 = bash $path2 | grep "\-w /var/run/utmp -p wa -k session" + $result22 = bash $path2 | grep "\-w /var/log/wtmp -p wa -k session" + $result23 = bash $path2 | grep "\-w /var/log/btmp -p wa -k session" + if($result11 -ne $null -and $result12 -ne $null -and $result13 -ne $null -and $result21 -ne $null -and $result22 -ne $null -and $result23 -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.3.12" + Task = "Ensure login and logout events are collected" + Test = { + $script = $commonPath + "6.3.3.12.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.13" + Task = "Ensure file deletion events by users are collected" + Test = { + $script = $commonPath + "6.3.3.13.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.14" + Task = "Ensure events that modify the system's Mandatory Access Controls are collected" + Test = { + $script = $commonPath + "6.3.3.14.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.15" + Task = "Ensure successful and unsuccessful attempts to use the chcon command are recorded" + Test = { + $script = $commonPath + "6.3.3.15.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.16" + Task = "Ensure successful and unsuccessful attempts to use the setfacl command are recorded" + Test = { + $script = $commonPath + "6.3.3.16.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.17" + Task = "Ensure successful and unsuccessful attempts to use the chacl command are recorded" + Test = { + $script = $commonPath + "6.3.3.17.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.18" + Task = "Ensure successful and unsuccessful attempts to use the usermod command are recorded" + Test = { + $script = $commonPath + "6.3.3.18.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.19" + Task = "Ensure kernel module loading unloading and modification is collected" + Test = { + $script = $commonPath + "6.3.3.19.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.20" + Task = "Ensure the audit configuration is immutable" + Test = { + $test1 = grep "^\s*[^#]" /etc/audit/rules.d/*.rules | tail -l + if($test1 -match "-e 2"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.3.21" + Task = "Ensure the running and on disk configuration is the same" + Test = { + $test1 = augenrules --check + if($test1 -match "/usr/sbin/augenrules: No change"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.4.1" + Task = "Ensure audit log files mode is configured" + Test = { + $script = $scriptPath + "6.3.4.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.2" + Task = "Ensure audit log files owner is configured" + Test = { + $script = $scriptPath + "6.3.4.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.3" + Task = "Ensure audit log files group owner is configured" + Test = { + $script = $scriptPath + "6.3.4.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.4" + Task = "Ensure the audit log file directory mode is configured" + Test = { + $script = $scriptPath + "6.3.4.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.5" + Task = "Ensure audit configuration files mode is configured" + Test = { + $script = $commonPath + "6.3.4.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.6" + Task = "Ensure audit configuration files owner is configured" + Test = { + $script = $commonPath + "6.3.4.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.7" + Task = "Ensure audit configuration files group owner is configured" + Test = { + $script = $commonPath + "6.3.4.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.8" + Task = "Ensure audit tools mode is configured" + Test = { + $script = $commonPath + "6.3.4.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.9" + Task = "Ensure audit tools owner is configured" + Test = { + $script = $commonPath + "6.3.4.9.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.10" + Task = "Ensure audit tools group owner is configured" + Test = { + $test1 = stat -Lc '%G' /sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules | awk '$1 != "root" {print}' + if($test1 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.1" + Task = "Ensure permissions on /etc/passwd are configured" + Test = { + $test1 = stat -c '%#a' /etc/passwd | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.2" + Task = "Ensure permissions on /etc/passwd- are configured" + Test = { + $test1 = stat -c '%#a' /etc/passwd- | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.3" + Task = "Ensure permissions on /etc/group are configured" + Test = { + $test1 = stat -c '%#a' /etc/group | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.4" + Task = "Ensure permissions on /etc/group- are configured" + Test = { + $test1 = stat -c '%#a' /etc/group- | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.5" + Task = "Ensure permissions on /etc/shadow are configured" + Test = { + $test1 = stat -c '%#a' /etc/shadow | grep -q "0640" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.6" + Task = "Ensure permissions on /etc/shadow- are configured" + Test = { + $test1 = stat -c '%#a' /etc/shadow- | grep -q "0640" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.7" + Task = "Ensure permissions on /etc/gshadow are configured" + Test = { + $test1 = stat -c '%#a' /etc/gshadow | grep -q "0640" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.8" + Task = "Ensure permissions on /etc/gshadow- are configured" + Test = { + $test1 = stat -c '%#a' /etc/gshadow- | grep -q "0640" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.9" + Task = "Ensure permissions on /etc/shells are configured" + Test = { + $script = $commonPath + "7.1.9.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "7.1.10" + Task = "Ensure permissions on /etc/security/opasswd are configured" + Test = { + $script = $commonPath + "7.1.10.sh" + $result = bash $script + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.11" + Task = "Ensure world writable files and directories are secured" + Test = { + #$partitions = mapfile -t partitions < (sudo fdisk -l | grep -o '/dev/[^ ]*') + #$test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -0002 + $script = $commonPath + "7.1.11.sh" + $result = bash $script + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.12" + Task = "Ensure no files or directories without an owner and a group exist" + Test = { + $script = $commonPath + "7.1.12.sh" + $result = bash $script + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.13" + Task = "Ensure SUID and SGID files are reviewed" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -4000 + $message = "" + foreach($line in $test1){ + $message += "
$line" + } + return @{ + Message = "Please review following list of files: $($message)" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "7.2.1" + Task = "Ensure accounts in /etc/passwd use shadowed passwords" + Test = { + $test1 = awk -F: '($2 != "x" ) { print $1 " is not set to shadowed passwords "}'/etc/passwd + if($test1 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.2" + Task = "Ensure /etc/shadow password fields are not empty" + Test = { + $test1 = awk -F: '($2 == "" ) { print $1 " does not have a password "}' /etc/shadow + if($test1 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.3" + Task = "Ensure all groups in /etc/passwd exist in /etc/group" + Test = { + $path = $scriptPath + "6.2.3.sh" + $result=bash $path + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.4" + Task = "Ensure shadow group is empty" + Test = { + $test1 = awk -F: '($1=="shadow") {print $NF}' /etc/group + $test2 = awk -F: -v GID="$(awk -F: '($1=="shadow") {print $3}' /etc/group)" '($4==GID) {print $1}' /etc/passwd + if($test1.Length -eq 0 -and $test2 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.5" + Task = "Ensure no duplicate UIDs exist" + Test = { + $path = $scriptPath + "6.2.5.sh" + $result=bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.6" + Task = "Ensure no duplicate GIDs exist" + Test = { + $path = $scriptPath + "6.2.6.sh" + $result=bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.7" + Task = "Ensure no duplicate user names exist" + Test = { + $path = $scriptPath + "6.2.7.sh" + $result=bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.8" + Task = "Ensure no duplicate group names exist" + Test = { + $path = $scriptPath + "6.2.8.sh" + $result=bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ # in CIS it's automated, but in Excelsheet it's manual + Id = "7.2.9" + Task = "Ensure local interactive user home directories are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ # in CIS it's automated, but in Excelsheet it's manual + Id = "7.2.10" + Task = "Ensure local interactive user dot files access is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} diff --git a/ATAPAuditor/AuditGroups/Enhanced security settings-FBPro-1.0#UserRights.ps1 b/ATAPAuditor/AuditGroups/Enhanced security settings-FBPro-1.0#UserRights.ps1 new file mode 100644 index 0000000..850ebb2 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Enhanced security settings-FBPro-1.0#UserRights.ps1 @@ -0,0 +1,184 @@ +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and + (Get-WindowsOptionalFeature -Online -FeatureName "Microsoft-Hyper-V").State -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "1.0" + Task = "Ensure 'Debug programs' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @() | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.1" + Task = "Ensure 'Enable DCOM Hardening' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\AppCompat" ` + -Name "RequireIntegrityActivationAuthenticationLevel" ` + | Select-Object -ExpandProperty "RequireIntegrityActivationAuthenticationLevel" + + if ($regValue -ne 0x00000001) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0x00000001" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.2" + Task = "Ensure 'Raise Authentication Level' is set to 'Raise the authentication level for all non-anonymous activation requests from Windows-based DCOM clients'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\AppCompat" ` + -Name "RaiseActivationAuthenticationLevel" ` + | Select-Object -ExpandProperty "RaiseActivationAuthenticationLevel" + + if ($regValue -ne 0x00000002) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0x00000002" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} \ No newline at end of file diff --git a/ATAPAuditor/AuditGroups/Google Chrome-CIS-2.0.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Google Chrome-CIS-2.0.0#RegistrySettings.ps1 new file mode 100644 index 0000000..804f2d9 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Google Chrome-CIS-2.0.0#RegistrySettings.ps1 @@ -0,0 +1,2402 @@ +[AuditTest] @{ + Id = "1.1.1" + Task = "(L1) Ensure 'Enable curtaining of remote access hosts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "RemoteAccessHostRequireCurtain" ` + | Select-Object -ExpandProperty "RemoteAccessHostRequireCurtain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "(L1) Ensure 'Allow gnubby authentication for remote access hosts' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "RemoteAccessHostAllowGnubbyAuth" ` + | Select-Object -ExpandProperty "RemoteAccessHostAllowGnubbyAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "(L1) Ensure 'Allow remote users to interact with elevated windows in remote assistance sessions' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "RemoteAccessHostAllowUiAccessForRemoteAssistance" ` + | Select-Object -ExpandProperty "RemoteAccessHostAllowUiAccessForRemoteAssistance" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2" + Task = "(L1) Ensure 'Continue running background apps when Google Chrome is closed' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "BackgroundModeEnabled" ` + | Select-Object -ExpandProperty "BackgroundModeEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3" + Task = "(L1) Ensure 'Ask where to save each file before downloading' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "PromptForDownloadLocation" ` + | Select-Object -ExpandProperty "PromptForDownloadLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.4" + Task = "(L1) Ensure 'Disable saving browser history' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "SavingBrowserHistoryDisabled" ` + | Select-Object -ExpandProperty "SavingBrowserHistoryDisabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.5" + Task = "(L1) Ensure 'Enable HTTP/0.9 support on non-default ports' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "Http09OnNonDefaultPortsEnabled" ` + | Select-Object -ExpandProperty "Http09OnNonDefaultPortsEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.6" + Task = "(L1) Ensure 'Enable component updates in Google Chrome' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "ComponentUpdatesEnabled" ` + | Select-Object -ExpandProperty "ComponentUpdatesEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.7" + Task = "(L1) Ensure 'Enable deprecated web platform features for a limited time' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\EnableDeprecatedWebPlatformFeatures" ` + -Name "\d+" ` + | Select-Object -ExpandProperty "\d+" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.8" + Task = "(L1) Ensure 'Enable third party software injection blocking' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "ThirdPartyBlockingEnabled" ` + | Select-Object -ExpandProperty "ThirdPartyBlockingEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.9" + Task = "(L1) Ensure 'Extend Flash content setting to all content' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "RunAllFlashInAllowMode" ` + | Select-Object -ExpandProperty "RunAllFlashInAllowMode" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.10" + Task = "(L1) Ensure 'Suppress the unsupported OS warning' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "SuppressUnsupportedOSWarning" ` + | Select-Object -ExpandProperty "SuppressUnsupportedOSWarning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.11" + Task = "(L1) Ensure 'Whether online OCSP/CRL checks are performed' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "EnableOnlineRevocationChecks" ` + | Select-Object -ExpandProperty "EnableOnlineRevocationChecks" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.12" + Task = "(L1) Ensure 'Allow WebDriver to Override Incompatible Policies' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "WebDriverOverridesIncompatiblePolicies" ` + | Select-Object -ExpandProperty "WebDriverOverridesIncompatiblePolicies" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.13" + Task = "(L1) Ensure 'Control SafeSites adult content filtering' is set to 'Enabled' with value 'Do not filter sites for adult content' specified" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "SafeSitesFilterBehavior" ` + | Select-Object -ExpandProperty "SafeSitesFilterBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.14" + Task = "(L1) Ensure 'Origins or hostname patterns for which restrictions on insecure origins should not apply' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\OverrideSecurityRestrictionsOnInsecureOrigin" ` + -Name "\d+" ` + | Select-Object -ExpandProperty "\d+" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.15" + Task = "(L1) Ensure 'Disable Certificate Transparency enforcement for a list of Legacy Certificate Authorities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\CertificateTransparencyEnforcementDisabledForLegacyCas" ` + -Name "\d+" ` + | Select-Object -ExpandProperty "\d+" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.16" + Task = "(L1) Ensure 'Disable Certificate Transparency enforcement for a list of URLs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\CertificateTransparencyEnforcementDisabledForUrls" ` + -Name "\d+" ` + | Select-Object -ExpandProperty "\d+" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.17" + Task = "(L1) Ensure 'Disable Certificate Transparency enforcement for a list of subjectPublicKeyInfo hashes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\CertificateTransparencyEnforcementDisabledForCas" ` + -Name "\d+" ` + | Select-Object -ExpandProperty "\d+" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.1" + Task = "(L1) Ensure 'Default Flash Setting' is set to 'Enabled' (Click to Play)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "DefaultPluginsSetting" ` + | Select-Object -ExpandProperty "DefaultPluginsSetting" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.2" + Task = "(L2) Ensure 'Default notification setting' is set to 'Enabled' with 'Do not allow any site to show desktop notifications'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "DefaultNotificationsSetting" ` + | Select-Object -ExpandProperty "DefaultNotificationsSetting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3" + Task = "(L2) Ensure 'Control use of the Web Bluetooth API' is set to 'Enabled' with 'Do not allow any site to request access to Bluetooth devices via the Web Bluetooth API'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "DefaultWebBluetoothGuardSetting" ` + | Select-Object -ExpandProperty "DefaultWebBluetoothGuardSetting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.4" + Task = "(L2) Ensure 'Control use of the WebUSB API' is set to 'Enabled' with 'Do not allow any site to request access to USB devices via the WebUSB API'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "DefaultWebUsbGuardSetting" ` + | Select-Object -ExpandProperty "DefaultWebUsbGuardSetting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.5" + Task = "(L1) Ensure 'Configure extension installation blacklist' is set to 'Enabled' (`"*`" for all extensions)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\ExtensionInstallBlacklist" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "*") { + return @{ + Message = "Registry value is '$regValue'. Expected: *" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.6.1" + Task = "(L1) Ensure 'Configure allowed app/extension types' is set to 'Enabled' with the values 'extension' specified" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\ExtensionAllowedTypes" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "extension") { + return @{ + Message = "Registry value is '$regValue'. Expected: extension" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.6.2" + Task = "(L1) Ensure 'Configure allowed app/extension types' is set to 'Enabled' with the value 'hosted_app'specified" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\ExtensionAllowedTypes" ` + -Name "2" ` + | Select-Object -ExpandProperty "2" + + if ($regValue -ne "hosted_app") { + return @{ + Message = "Registry value is '$regValue'. Expected: hosted_app" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.6.3" + Task = "(L1) Ensure 'Configure allowed app/extension types' is set to 'Enabled' with the value 'platform_app' specified" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\ExtensionAllowedTypes" ` + -Name "3" ` + | Select-Object -ExpandProperty "3" + + if ($regValue -ne "platform_app") { + return @{ + Message = "Registry value is '$regValue'. Expected: platform_app" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.6.4" + Task = "(L1) Ensure 'Configure allowed app/extension types' is set to 'Enabled' with the value 'theme'specified" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\ExtensionAllowedTypes" ` + -Name "4" ` + | Select-Object -ExpandProperty "4" + + if ($regValue -ne "theme") { + return @{ + Message = "Registry value is '$regValue'. Expected: theme" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.7" + Task = "(L2) Ensure 'Configure native messaging blacklist' is set to 'Enabled' (`"*`" for all messaging applications)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\NativeMessagingBlacklist" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "*") { + return @{ + Message = "Registry value is '$regValue'. Expected: *" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.8" + Task = "(L1) Ensure 'Enable saving passwords to the password manager' is Configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "PasswordManagerEnabled" ` + | Select-Object -ExpandProperty "PasswordManagerEnabled" + + if (($regValue -ne 1) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.9" + Task = "(L1) Ensure 'Supported authentication schemes' is set to 'Enabled' (ntlm, negotiate)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "AuthSchemes" ` + | Select-Object -ExpandProperty "AuthSchemes" + + if ($regValue -ne "ntlm, negotiate") { + return @{ + Message = "Registry value is '$regValue'. Expected: ntlm, negotiate" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.10" + Task = "(L1) Ensure 'Choose how to specify proxy server settings' is not set to 'Enabled' with 'Auto detect proxy settings'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "ProxyMode" ` + | Select-Object -ExpandProperty "ProxyMode" + + if ($regValue -ne "auto_detect") { + return @{ + Message = "Registry value is '$regValue'. Expected: auto_detect" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.11" + Task = "(L1) Ensure 'Allow running plugins that are outdated' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "AllowOutdatedPlugins" ` + | Select-Object -ExpandProperty "AllowOutdatedPlugins" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.12" + Task = "(L1) Ensure 'Enable Google Cloud Print Proxy' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "CloudPrintProxyEnabled" ` + | Select-Object -ExpandProperty "CloudPrintProxyEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.13" + Task = "(L1) Ensure 'Enable Site Isolation for every site' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "SitePerProcess" ` + | Select-Object -ExpandProperty "SitePerProcess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.14" + Task = "(L1) Ensure 'Allow download restrictions' is set to 'Enabled' with 'Block dangerous downloads' specified." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "DownloadRestrictions" ` + | Select-Object -ExpandProperty "DownloadRestrictions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.15" + Task = "(L1) Ensure 'Disable proceeding from the Safe Browsing warning page' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "DisableSafeBrowsingProceedAnyway" ` + | Select-Object -ExpandProperty "DisableSafeBrowsingProceedAnyway" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.16" + Task = "(L1) Ensure 'Notify a user that a browser relaunch or device restart is recommended or required' is set to 'Enabled' with 'Show a recurring prompt to the user indication that a relaunch is required' specified" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "RelaunchNotification" ` + | Select-Object -ExpandProperty "RelaunchNotification" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.17" + Task = "(L1) Ensure 'Set the time period for update notifications' is set to 'Enabled' with '86400000' (1 day) specified" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "RelaunchNotificationPeriod" ` + | Select-Object -ExpandProperty "RelaunchNotificationPeriod" + + if (($regValue -gt 86400000)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 86400000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.18" + Task = "(L2) Ensure 'Whether online OCSP/CRL checks are required for local trust anchors' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "RequireOnlineRevocationChecksForLocalAnchors" ` + | Select-Object -ExpandProperty "RequireOnlineRevocationChecksForLocalAnchors" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.19" + Task = "(L1) Ensure 'Enable Chrome Cleanup on Windows' is Configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "ChromeCleanupEnabled" ` + | Select-Object -ExpandProperty "ChromeCleanupEnabled" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0 or x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.20" + Task = "(L2) Ensure 'Use built-in DNS client' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "BuiltInDnsClientEnabled" ` + | Select-Object -ExpandProperty "BuiltInDnsClientEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.21" + Task = "(L1) Ensure 'Update policy override' is set to 'Enabled' with 'Always allow updates (recommended)' or 'Automatic silent updates' specified" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Update" ` + -Name "Update{8A69D345-D564-463C-AFF1-A69D9E530F96}" ` + | Select-Object -ExpandProperty "Update{8A69D345-D564-463C-AFF1-A69D9E530F96}" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.1" + Task = "(L2) Ensure 'Default cookies setting' is set to 'Enabled' (Keep cookies for the duration of the session)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "DefaultCookiesSetting" ` + | Select-Object -ExpandProperty "DefaultCookiesSetting" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.2" + Task = "(L1) Ensure 'Default geolocation setting' is set to 'Enabled' with 'Do not allow any site to track the users' physical location'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "DefaultGeolocationSetting" ` + | Select-Object -ExpandProperty "DefaultGeolocationSetting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.3" + Task = "(L1) Ensure 'Enable Google Cast' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "EnableMediaRouter" ` + | Select-Object -ExpandProperty "EnableMediaRouter" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.4" + Task = "(L1) Ensure 'Block third party cookies' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "BlockThirdPartyCookies" ` + | Select-Object -ExpandProperty "BlockThirdPartyCookies" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.5" + Task = "(L1) Ensure 'Enable reporting of usage and crash-related data' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "MetricsReportingEnabled" ` + | Select-Object -ExpandProperty "MetricsReportingEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.6" + Task = "(L1) Ensure 'Control how Chrome Cleanup reports data to Google' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "ChromeCleanupReportingEnabled" ` + | Select-Object -ExpandProperty "ChromeCleanupReportingEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.7" + Task = "(L1) Ensure 'Browser sign in settings' is set to 'Enabled' with 'Disabled browser sign-in' specified" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "BrowserSignin" ` + | Select-Object -ExpandProperty "BrowserSignin" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.8" + Task = "(L1) Ensure 'Enable Translate' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "TranslateEnabled" ` + | Select-Object -ExpandProperty "TranslateEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.9" + Task = "(L1) Ensure 'Enable network prediction' is set to 'Enabled' with 'Do not predict actions on any network connection' selected" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "NetworkPredictionOptions" ` + | Select-Object -ExpandProperty "NetworkPredictionOptions" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.10" + Task = "(L1) Ensure 'Enable search suggestions' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "SearchSuggestEnabled" ` + | Select-Object -ExpandProperty "SearchSuggestEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.11" + Task = "(L1) Ensure 'Enable or disable spell checking web service' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "SpellCheckServiceEnabled" ` + | Select-Object -ExpandProperty "SpellCheckServiceEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.12" + Task = "(L1) Ensure 'Enable alternate error pages' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "AlternateErrorPagesEnabled" ` + | Select-Object -ExpandProperty "AlternateErrorPagesEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.13" + Task = "(L1) Ensure 'Disable synchronization of data with Google' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "SyncDisabled" ` + | Select-Object -ExpandProperty "SyncDisabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.14" + Task = "(L1) Ensure 'Enable Safe Browsing for trusted sources' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "SafeBrowsingForTrustedSourcesEnabled" ` + | Select-Object -ExpandProperty "SafeBrowsingForTrustedSourcesEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.15" + Task = "(L1) Ensure 'Enable URL-keyed anonymized data collection' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "UrlKeyedAnonymizedDataCollectionEnabled" ` + | Select-Object -ExpandProperty "UrlKeyedAnonymizedDataCollectionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.16" + Task = "(L1) Ensure 'Enable deleting browser and download history' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "AllowDeletingBrowserHistory" ` + | Select-Object -ExpandProperty "AllowDeletingBrowserHistory" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.1.1" + Task = "(L1) Ensure 'Enable firewall traversal from remote access host' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "RemoteAccessHostFirewallTraversal" ` + | Select-Object -ExpandProperty "RemoteAccessHostFirewallTraversal" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.1.2" + Task = "(L1) Ensure 'Enable or disable PIN-less authentication for remote access hosts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "RemoteAccessHostAllowClientPairing" ` + | Select-Object -ExpandProperty "RemoteAccessHostAllowClientPairing" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.1.3" + Task = "(L1) Ensure 'Enable the use of relay servers by the remote access host' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "RemoteAccessHostAllowRelayedConnection" ` + | Select-Object -ExpandProperty "RemoteAccessHostAllowRelayedConnection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.1.4" + Task = "(L1) Ensure 'Configure the required domain names for remote access clients' is set to 'Enabled' with a domain defined" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\RemoteAccessHostClientDomainList" ` + -Name "\d+" ` + | Select-Object -ExpandProperty "\d+" + + if ($regValue -notmatch ".*") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.*'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1" + Task = "(L1) Ensure 'Enable submission of documents to Google Cloud print' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "CloudPrintSubmitEnabled" ` + | Select-Object -ExpandProperty "CloudPrintSubmitEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2" + Task = "(L1) Ensure 'Import saved passwords from default browser on first run' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "ImportSavedPasswords" ` + | Select-Object -ExpandProperty "ImportSavedPasswords" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.3" + Task = "(L1) Ensure 'Enable AutoFill for credit cards' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "AutofillCreditCardEnabled" ` + | Select-Object -ExpandProperty "AutofillCreditCardEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.4" + Task = "(L1) Ensure 'Enable AutoFill for addresses' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome" ` + -Name "AutofillAddressEnabled" ` + | Select-Object -ExpandProperty "AutofillAddressEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Google Chrome-DISA-V1R15#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Google Chrome-DISA-V1R15#RegistrySettings.ps1 new file mode 100644 index 0000000..a2ce833 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Google Chrome-DISA-V1R15#RegistrySettings.ps1 @@ -0,0 +1,1296 @@ +[AuditTest] @{ + Id = "DTBC-0001" + Task = "Firewall traversal from remote host must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "RemoteAccessHostFirewallTraversal" ` + | Select-Object -ExpandProperty "RemoteAccessHostFirewallTraversal" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0003" + Task = "Sites ability for showing desktop notifications must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "DefaultNotificationsSetting" ` + | Select-Object -ExpandProperty "DefaultNotificationsSetting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0004" + Task = "Sites ability to show pop-ups must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "DefaultPopupsSetting" ` + | Select-Object -ExpandProperty "DefaultPopupsSetting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0002" + Task = "Site tracking users location must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "DefaultGeolocationSetting" ` + | Select-Object -ExpandProperty "DefaultGeolocationSetting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0005" + Task = "Extensions installation must be blacklisted by default." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\ExtensionInstallBlacklist" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "*") { + return @{ + Message = "Registry value is '$regValue'. Expected: *" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0006" + Task = "Extensions that are approved for use must be whitelisted." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\ExtensionInstallWhitelist" ` + -Name "ExtensionInstallWhitelist" ` + | Select-Object -ExpandProperty "ExtensionInstallWhitelist" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0009" + Task = "Default search provider must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "DefaultSearchProviderEnabled" ` + | Select-Object -ExpandProperty "DefaultSearchProviderEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0011" + Task = "The Password Manager must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "PasswordManagerEnabled" ` + | Select-Object -ExpandProperty "PasswordManagerEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0013" + Task = "The running of outdated plugins must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome" ` + -Name "AllowOutdatedPlugins" ` + | Select-Object -ExpandProperty "AllowOutdatedPlugins" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0015" + Task = "Third party cookies must be blocked." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "BlockThirdPartyCookies" ` + | Select-Object -ExpandProperty "BlockThirdPartyCookies" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0017" + Task = "Background processing must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "BackgroundModeEnabled" ` + | Select-Object -ExpandProperty "BackgroundModeEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0019" + Task = "3D Graphics APIs must be disabled. (Note: If 3D APIs are required by mission, this is not a finding.)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "Disable3DAPIs" ` + | Select-Object -ExpandProperty "Disable3DAPIs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0020" + Task = "Google Data Synchronization must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "SyncDisabled" ` + | Select-Object -ExpandProperty "SyncDisabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0021" + Task = "The URL protocol schema javascript must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\URLBlacklist" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "javascript://*") { + return @{ + Message = "Registry value is '$regValue'. Expected: javascript://*" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0023" + Task = "Cloud print sharing must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "CloudPrintProxyEnabled" ` + | Select-Object -ExpandProperty "CloudPrintProxyEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0025" + Task = "Network prediction must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "NetworkPredictionOptions" ` + | Select-Object -ExpandProperty "NetworkPredictionOptions" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0026" + Task = "Metrics reporting to Google must be disabled. (Note: This policy will only display in the chrome://policy tab on domain joined systems. On standalone systems, the policy will not display.)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "MetricsReportingEnabled" ` + | Select-Object -ExpandProperty "MetricsReportingEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0027" + Task = "Search suggestions must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "SearchSuggestEnabled" ` + | Select-Object -ExpandProperty "SearchSuggestEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0029" + Task = "Importing of saved passwords must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "ImportSavedPasswords" ` + | Select-Object -ExpandProperty "ImportSavedPasswords" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0030" + Task = "Incognito mode must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "IncognitoModeAvailability" ` + | Select-Object -ExpandProperty "IncognitoModeAvailability" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0037" + Task = "Online revocation checks must be done." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "EnableOnlineRevocationChecks" ` + | Select-Object -ExpandProperty "EnableOnlineRevocationChecks" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0038" + Task = "Safe Browsing must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "SafeBrowsingEnabled" ` + | Select-Object -ExpandProperty "SafeBrowsingEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0039" + Task = "Browser history must be saved." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "SavingBrowserHistoryDisabled" ` + | Select-Object -ExpandProperty "SavingBrowserHistoryDisabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0040" + Task = "Default behavior must block webpages from automatically running plugins." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "DefaultPluginsSetting" ` + | Select-Object -ExpandProperty "DefaultPluginsSetting" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0051" + Task = "URLs must be whitelisted for plugin use" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "PluginsAllowedForUrls" ` + | Select-Object -ExpandProperty "PluginsAllowedForUrls" + + if ($regValue -ne "Suggested: the set or subset of [*.]mil and [*.]gov") { + return @{ + Message = "Registry value is '$regValue'. Expected: Suggested: the set or subset of [*.]mil and [*.]gov" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0052" + Task = "Deletion of browser history must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "AllowDeletingBrowserHistory" ` + | Select-Object -ExpandProperty "AllowDeletingBrowserHistory" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0053" + Task = "Prompt for download location must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "PromptForDownloadLocation" ` + | Select-Object -ExpandProperty "PromptForDownloadLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0064" + Task = "Autoplay must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "AutoplayAllowed" ` + | Select-Object -ExpandProperty "AutoplayAllowed" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0056" + Task = "Chrome must be configured to allow only TLS." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "SSLVersionMin" ` + | Select-Object -ExpandProperty "SSLVersionMin" + + if ($regValue -ne "tls1.1") { + return @{ + Message = "Registry value is '$regValue'. Expected: tls1.1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0057" + Task = "Safe Browsing Extended Reporting must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "SafeBrowsingExtendedReportingEnabled" ` + | Select-Object -ExpandProperty "SafeBrowsingExtendedReportingEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0058" + Task = "WebUSB must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "DefaultWebUsbGuardSetting" ` + | Select-Object -ExpandProperty "DefaultWebUsbGuardSetting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0060" + Task = "Chrome Cleanup must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "ChromeCleanupEnabled" ` + | Select-Object -ExpandProperty "ChromeCleanupEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0061" + Task = "Chrome Cleanup reporting must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "ChromeCleanupReportingEnabled" ` + | Select-Object -ExpandProperty "ChromeCleanupReportingEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0063" + Task = "Google Cast must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "EnableMediaRouter" ` + | Select-Object -ExpandProperty "EnableMediaRouter" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0066" + Task = "Anonymized data collection must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "UrlKeyedAnonymizedDataCollectionEnabled" ` + | Select-Object -ExpandProperty "UrlKeyedAnonymizedDataCollectionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBC-0067" + Task = "Collection of WebRTC event logs must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\" ` + -Name "WebRtcEventLogCollectionAllowed" ` + | Select-Object -ExpandProperty "WebRtcEventLogCollectionAllowed" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Edge-CIS-2.0.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Edge-CIS-2.0.0#RegistrySettings.ps1 new file mode 100644 index 0000000..41af9a6 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Edge-CIS-2.0.0#RegistrySettings.ps1 @@ -0,0 +1,4854 @@ +[AuditTest] @{ + Id = "1.2.1" + Task = "(L1) Ensure 'Enable Google Cast' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "EnableMediaRouter" ` + | Select-Object -ExpandProperty "EnableMediaRouter" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.1" + Task = "(L2) Ensure 'Allow read access via the File System API on these sites' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "FileSystemReadAskForUrls" ` + | Select-Object -ExpandProperty "FileSystemReadAskForUrls" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.2" + Task = "(L1) Ensure 'Choose whether users can receive customized background images and text, suggestions, notifications, and tips for Microsoft services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "SpotlightExperiencesAndRecommendationsEnabled" ` + | Select-Object -ExpandProperty "SpotlightExperiencesAndRecommendationsEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.3" + Task = "(L1) Ensure 'Control use of insecure content exceptions' is set to 'Enabled: Do not allow any site to load mixed content'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DefaultinsecurecontentSetting" ` + | Select-Object -ExpandProperty "DefaultinsecurecontentSetting" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.4" + Task = "(L2) Ensure 'Control use of JavaScript JIT' is set to 'Enabled: Do not allow any site to run JavaScript JIT'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DefaultJavaScriptJitSetting" ` + | Select-Object -ExpandProperty "DefaultJavaScriptJitSetting" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.5" + Task = "(L2) Ensure 'Control use of the File System API for reading' is set to 'Enabled: Don't allow any site to request read access to files and directories'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DefaultFileSystemReadGuardSetting" ` + | Select-Object -ExpandProperty "DefaultFileSystemReadGuardSetting" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.6" + Task = "(L1) Ensure 'Control use of the File System API for writing' is set to 'Enabled: Don't allow any site to request write access to files and directories'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DefaultFileSystemWriteGuardSetting" ` + | Select-Object -ExpandProperty "DefaultFileSystemWriteGuardSetting" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.7" + Task = "(L2) Ensure 'Control use of the Web Bluetooth API' is set to 'Enabled: Do not allow any site to request access to Bluetooth'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DefaultWebBluetoothGuardSetting" ` + | Select-Object -ExpandProperty "DefaultWebBluetoothGuardSetting" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.8" + Task = "(L2) Ensure 'Control use of the WebHID API' is set to 'Enabled: Do not allow any site to request access to HID devices via the WebHID API'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DefaultWebHidGuardSetting" ` + | Select-Object -ExpandProperty "DefaultWebHidGuardSetting" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.9" + Task = "(L1) Ensure 'Default automatic downloads setting' is set to 'Enabled: Don´t allow any website to perform automatic downloads'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DefaultAutomaticDownloadsSetting" ` + | Select-Object -ExpandProperty "DefaultAutomaticDownloadsSetting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.10" + Task = "(L1) Ensure 'Default geolocation setting' is set to 'Enabled: Don't allow any site to track users physical location'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DefaultGeolocationSetting" ` + | Select-Object -ExpandProperty "DefaultGeolocationSetting" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.5.1" + Task = "(L1) Ensure 'Configure users ability to override feature flags' is set to 'Enabled: Prevent users from overriding feature flags'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "FeatureFlagOverridesControl" ` + | Select-Object -ExpandProperty "FeatureFlagOverridesControl" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.6.1" + Task = "(L2) Ensure 'Configure extension management settings' is set to 'Enabled: *'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ExtensionSettings" ` + | Select-Object -ExpandProperty "ExtensionSettings" + + if ($regValue -ne "*") { + return @{ + Message = "Registry value is '$regValue'. Expected: *" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.7.1" + Task = "(L1) Ensure 'Allow Basic authentication for HTTP' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "BasicAuthOverHttpEnabled" ` + | Select-Object -ExpandProperty "BasicAuthOverHttpEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.7.2" + Task = "(L1) Ensure 'Allow cross-origin HTTP Basic Auth prompts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "AllowCrossOriginAuthPrompt" ` + | Select-Object -ExpandProperty "AllowCrossOriginAuthPrompt" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.7.3" + Task = "(L2) Ensure 'Supported authentication schemes' is set to 'Enabled: ntlm, negotiate'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "AuthSchemes" ` + | Select-Object -ExpandProperty "AuthSchemes" + + if ($regValue -ne "ntlm, negotiate") { + return @{ + Message = "Registry value is '$regValue'. Expected: ntlm, negotiate" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.8.1" + Task = "(L1) Ensure 'Enable the linked account feature' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "LinkedAccountEnabled" ` + | Select-Object -ExpandProperty "LinkedAccountEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.8.2" + Task = "(L1) Ensure 'Guided Switch Enabled' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "GuidedSwitchEnabled" ` + | Select-Object -ExpandProperty "GuidedSwitchEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.13.1" + Task = "(L1) Ensure 'Enable saving passwords to the password manager' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "PasswordManagerEnabled" ` + | Select-Object -ExpandProperty "PasswordManagerEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.14.1" + Task = "(L1) Ensure 'Enable startup boost' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "StartupBoostEnabled" ` + | Select-Object -ExpandProperty "StartupBoostEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.17.1" + Task = "(L1) Ensure 'Specifies whether to allow websites to make requests to more-private network endpoints' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "InsecurePrivateNetworkRequestsAllowed" ` + | Select-Object -ExpandProperty "InsecurePrivateNetworkRequestsAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.20.1" + Task = "(L1) Ensure 'Configure Microsoft Defender SmartScreen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "SmartScreenEnabled" ` + | Select-Object -ExpandProperty "SmartScreenEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.20.2" + Task = "(L1) Ensure 'Configure Microsoft Defender SmartScreen to block potentially unwanted apps' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "SmartScreenPuaEnabled" ` + | Select-Object -ExpandProperty "SmartScreenPuaEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.20.3" + Task = "(L1) Ensure 'Enable Microsoft Defender SmartScreen DNS requests' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "SmartScreenDnsRequestsEnabled" ` + | Select-Object -ExpandProperty "SmartScreenDnsRequestsEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.20.4" + Task = "(L1) Ensure 'Force Microsoft Defender SmartScreen checks on downloads from trusted sources' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "SmartScreenForTrustedDownloadsEnabled" ` + | Select-Object -ExpandProperty "SmartScreenForTrustedDownloadsEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.20.5" + Task = "(L1) Ensure 'Prevent bypassing Microsoft Defender SmartScreen prompts for sites' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "PreventSmartScreenPromptOverride" ` + | Select-Object -ExpandProperty "PreventSmartScreenPromptOverride" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.20.6" + Task = "(L1) Ensure 'Prevent bypassing of Microsoft Defender SmartScreen warnings about downloads' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "PreventSmartScreenPromptOverrideForFiles" ` + | Select-Object -ExpandProperty "PreventSmartScreenPromptOverrideForFiles" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.22.1" + Task = "(L1) Ensure 'Configure Edge TyposquattingChecker' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "TyposquattingCheckerEnabled" ` + | Select-Object -ExpandProperty "TyposquattingCheckerEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.23" + Task = "(L1) Ensure 'Ads setting for sites with intrusive ads' is set to 'Enabled: Block ads on sites with intrusive ads'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "AdsSettingForIntrusiveAdsSites" ` + | Select-Object -ExpandProperty "AdsSettingForIntrusiveAdsSites" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.24" + Task = "(L1) Ensure 'Allow download restrictions' is set to 'Enabled: Block potentially dangerous downloads'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DownloadRestrictions" ` + | Select-Object -ExpandProperty "DownloadRestrictions" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.25" + Task = "(L2) Ensure 'Allow features to download assets from the Asset Delivery Service' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "EdgeAssetDeliveryServiceEnabled" ` + | Select-Object -ExpandProperty "EdgeAssetDeliveryServiceEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.26" + Task = "(L2) Ensure 'Allow file selection dialogs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "AllowFileSelectionDialogs" ` + | Select-Object -ExpandProperty "AllowFileSelectionDialogs" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.27" + Task = "(L1) Ensure 'Allow Google Cast to connect to Cast devices on all IP addresses' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "MediaRouterCastAllowAllIPs" ` + | Select-Object -ExpandProperty "MediaRouterCastAllowAllIPs" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.28" + Task = "(L1) Ensure 'Allow import of data from other browsers on each Microsoft Edge launch' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ImportOnEachLaunch" ` + | Select-Object -ExpandProperty "ImportOnEachLaunch" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.29" + Task = "(L1) Ensure 'Allow importing of autofill form data' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ImportAutofillFormData" ` + | Select-Object -ExpandProperty "ImportAutofillFormData" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.30" + Task = "(L1) Ensure 'Allow importing of browser settings' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ImportBrowserSettings" ` + | Select-Object -ExpandProperty "ImportBrowserSettings" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.31" + Task = "(L1) Ensure 'Allow importing of home page settings' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ImportHomepage" ` + | Select-Object -ExpandProperty "ImportHomepage" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.32" + Task = "(L1) Ensure 'Allow importing of payment info' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ImportPaymentInfo" ` + | Select-Object -ExpandProperty "ImportPaymentInfo" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.33" + Task = "(L1) Ensure 'Allow importing of saved passwords' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ImportSavedPasswords" ` + | Select-Object -ExpandProperty "ImportSavedPasswords" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.34" + Task = "(L1) Ensure 'Allow importing of search engine settings' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ImportSearchEngine" ` + | Select-Object -ExpandProperty "ImportSearchEngine" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.35" + Task = "(L1) Ensure 'Allow managed extensions to use the Enterprise Hardware Platform API' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "EnterpriseHardwarePlatformAPIEnabled" ` + | Select-Object -ExpandProperty "EnterpriseHardwarePlatformAPIEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.36" + Task = "(L2) Ensure 'Allow or block audio capture' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "AudioCaptureAllowed" ` + | Select-Object -ExpandProperty "AudioCaptureAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.37" + Task = "(L2) Ensure 'Allow or block video capture' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "VideoCaptureAllowed" ` + | Select-Object -ExpandProperty "VideoCaptureAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.38" + Task = "(L2) Ensure 'Allow or deny screen capture' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ScreenCaptureAllowed" ` + | Select-Object -ExpandProperty "ScreenCaptureAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.39" + Task = "(L1) Ensure 'Allow personalization of ads, Microsoft Edge, search, news and other Microsoft services by sending browsing history, favorites and collections, usage and other browsing data to Microsoft' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "PersonalizationReportingEnabled" ` + | Select-Object -ExpandProperty "PersonalizationReportingEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.40" + Task = "(L1) Ensure 'Allow queries to a Browser Network Time service' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "BrowserNetworkTimeQueriesEnabled" ` + | Select-Object -ExpandProperty "BrowserNetworkTimeQueriesEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.41" + Task = "(L1) Ensure 'Allow remote debugging' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "RemoteDebuggingAllowed" ` + | Select-Object -ExpandProperty "RemoteDebuggingAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.42" + Task = "(L1) Ensure 'Allow the audio sandbox to run' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "AudioSandboxEnabled" ` + | Select-Object -ExpandProperty "AudioSandboxEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.43" + Task = "(L2) Ensure 'Allow unconfigured sites to be reloaded in Internet Explorer mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "InternetExplorerIntegrationReloadInIEModeAllowed" ` + | Select-Object -ExpandProperty "InternetExplorerIntegrationReloadInIEModeAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.44" + Task = "(L1) Ensure 'Allow user feedback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "UserFeedbackAllowed" ` + | Select-Object -ExpandProperty "UserFeedbackAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.45" + Task = "(L2) Ensure 'Allow users to open files using the ClickOnce protocol' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ClickOnceEnabled" ` + | Select-Object -ExpandProperty "ClickOnceEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.46" + Task = "(L2) Ensure 'Allow users to open files using the DirectInvoke protocol' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DirectInvokeEnabled" ` + | Select-Object -ExpandProperty "DirectInvokeEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.47" + Task = "(L2) Ensure 'Allow users to proceed from the HTTPS warning page' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "SSLErrorOverrideAllowed" ` + | Select-Object -ExpandProperty "SSLErrorOverrideAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.48" + Task = "(L1) Ensure 'Allow websites to query for available payment methods' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "PaymentMethodQueryEnabled" ` + | Select-Object -ExpandProperty "PaymentMethodQueryEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.49" + Task = "(L2) Ensure 'AutoLaunch Protocols Component Enabled' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "AutoLaunchProtocolsComponentEnabled" ` + | Select-Object -ExpandProperty "AutoLaunchProtocolsComponentEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.50" + Task = "(L1) Ensure 'Automatically import another browser's data and settings at first run' is set to 'Enabled: Disables automatic import, and the import section of the first-run experience is skipped'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "AutoImportAtFirstRun" ` + | Select-Object -ExpandProperty "AutoImportAtFirstRun" + + if (($regValue -ne 4)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.51" + Task = "(L2) Ensure 'Block third party cookies' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "BlockThirdPartyCookies" ` + | Select-Object -ExpandProperty "BlockThirdPartyCookies" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.52" + Task = "(L1) Ensure 'Block tracking of users' web-browsing activity' is set to 'Enabled: Balanced (Blocks harmful trackers and trackers from sites user has not visited; content and ads will be less personalized)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "TrackingPrevention" ` + | Select-Object -ExpandProperty "TrackingPrevention" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.53" + Task = "(L2) Ensure 'Browser sign-in settings' is set to 'Enabled: Disable browser sign-in'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "BrowserSignin" ` + | Select-Object -ExpandProperty "BrowserSignin" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.54" + Task = "(L1) Ensure 'Clear browsing data when Microsoft Edge closes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ClearBrowsingDataOnExit" ` + | Select-Object -ExpandProperty "ClearBrowsingDataOnExit" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.55" + Task = "(L1) Ensure 'Clear cached images and files when Microsoft Edge closes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ClearCachedImagesAndFilesOnExit" ` + | Select-Object -ExpandProperty "ClearCachedImagesAndFilesOnExit" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.56" + Task = "(L1) Ensure 'Clear history for IE and IE mode every time you exit' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "InternetExplorerModeclearDataOnExitEnabled" ` + | Select-Object -ExpandProperty "InternetExplorerModeclearDataOnExitEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.57" + Task = "(L1) Ensure 'Configure browser process code integrity guard setting' is set to 'Enabled: Enable code integrity guard enforcement in the browser process'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "browserCodeIntegritySetting" ` + | Select-Object -ExpandProperty "browserCodeIntegritySetting" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.58" + Task = "(L1) Ensure 'Configure InPrivate mode availability' is set to 'Enabled: InPrivate mode disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "InPrivateModeAvailability" ` + | Select-Object -ExpandProperty "InPrivateModeAvailability" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.59" + Task = "(L2) Ensure 'Configure Online Text To Speech' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ConfigureOnlineTextToSpeech" ` + | Select-Object -ExpandProperty "ConfigureOnlineTextToSpeech" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.60" + Task = "(L1) Ensure 'Configure Related Matches in Find on Page' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "RelatedMatchesCloudServiceEnabled" ` + | Select-Object -ExpandProperty "RelatedMatchesCloudServiceEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.61" + Task = "(L2) Ensure 'Configure Speech Recognition' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "SpeechRecognitionEnabled" ` + | Select-Object -ExpandProperty "SpeechRecognitionEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.62" + Task = "(L1) Ensure 'Configure the list of names that will bypass the HSTS policy check' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "HSTSPolicyBypassList" ` + | Select-Object -ExpandProperty "HSTSPolicyBypassList" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.63 A" + Task = "(L1) Ensure 'Configure the list of types that are excluded from synchronization' is set to 'Enabled' (passwords)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\SyncTypesListDisabled" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "passwords") { + return @{ + Message = "Registry value is '$regValue'. Expected: passwords" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.63 B" + Task = "(L2) Ensure 'Configure the list of types that are excluded from synchronization' is set to 'Enabled' (settings)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\SyncTypesListDisabled" ` + -Name "2" ` + | Select-Object -ExpandProperty "2" + + if ($regValue -ne "settings") { + return @{ + Message = "Registry value is '$regValue'. Expected: settings" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.63 C" + Task = " (L2) Ensure 'Configure the list of types that are excluded from synchronization' is set to 'Enabled' (favorites)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\SyncTypesListDisabled" ` + -Name "3" ` + | Select-Object -ExpandProperty "3" + + if ($regValue -ne "favorites") { + return @{ + Message = "Registry value is '$regValue'. Expected: favorites" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.63 D" + Task = "(L2) Ensure 'Configure the list of types that are excluded from synchronization' is set to 'Enabled' (addressesAndMore)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\SyncTypesListDisabled" ` + -Name "4" ` + | Select-Object -ExpandProperty "4" + + if ($regValue -ne "addressesAndMore") { + return @{ + Message = "Registry value is '$regValue'. Expected: addressesAndMore" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.63 E" + Task = "(L2) Ensure 'Configure the list of types that are excluded from synchronization' is set to 'Enabled' (extensions)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\SyncTypesListDisabled" ` + -Name "5" ` + | Select-Object -ExpandProperty "5" + + if ($regValue -ne "extensions") { + return @{ + Message = "Registry value is '$regValue'. Expected: extensions" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.63 F" + Task = "(L2) Ensure 'Configure the list of types that are excluded from synchronization' is set to 'Enabled' (collections)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\SyncTypesListDisabled" ` + -Name "6" ` + | Select-Object -ExpandProperty "6" + + if ($regValue -ne "collections") { + return @{ + Message = "Registry value is '$regValue'. Expected: collections" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.64" + Task = "(L1) Ensure 'Configure the Share experience' is set to 'Enabled: Don't allow using the Share experience'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ConfigureShare" ` + | Select-Object -ExpandProperty "ConfigureShare" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.65" + Task = "(L1) Ensure 'Configure whether form data and HTTP headers will be sent when entering or exiting Internet Explorer mode' is set to 'Enabled: Do not send form data or headers'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "InternetExplorerIntegrationComplexNavDataTypes" ` + | Select-Object -ExpandProperty "InternetExplorerIntegrationComplexNavDataTypes" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.66" + Task = "(L1) Ensure 'Continue running background apps after Microsoft Edge closes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "BackgroundModeEnabled" ` + | Select-Object -ExpandProperty "BackgroundModeEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.67" + Task = "(L1) Ensure 'Control communication with the Experimentation and Configuration Service' is set to 'Enabled: Disable communication with the Experimentation and Configuration Service'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ExperimentationAndConfigurationServiceControl" ` + | Select-Object -ExpandProperty "ExperimentationAndConfigurationServiceControl" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.68" + Task = "(L2) Ensure 'Control use of the Headless Mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "HeadlessModeEnabled" ` + | Select-Object -ExpandProperty "HeadlessModeEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.69" + Task = "(L2) Ensure 'Control use of the Serial API' is set to 'Enable: Do not allow any site to request access to serial ports via the Serial API'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DefaultSerialGuardSetting" ` + | Select-Object -ExpandProperty "DefaultSerialGuardSetting" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.70" + Task = "(L2) Ensure 'Control where security restrictions on insecure origins apply' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "OverrideSecurityRestrictionsOnInsecureOriginDesc" ` + | Select-Object -ExpandProperty "OverrideSecurityRestrictionsOnInsecureOriginDesc" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.71" + Task = "(L2) Ensure 'Default sensor setting' is set to 'Enabled: Do not allow any site to access sensors'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DefaultSensorsSetting" ` + | Select-Object -ExpandProperty "DefaultSensorsSetting" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.72" + Task = "(L1) Ensure 'Delete old browser data on migration' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DeleteDataOnMigration" ` + | Select-Object -ExpandProperty "DeleteDataOnMigration" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.73" + Task = "(L1) Ensure 'Disable saving browser history' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "SavingBrowserHistoryDisabled" ` + | Select-Object -ExpandProperty "SavingBrowserHistoryDisabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.74" + Task = "(L1) Ensure 'Disable synchronization of data using Microsoft sync services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "SyncDisabled" ` + | Select-Object -ExpandProperty "SyncDisabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.75" + Task = "(L1) Ensure 'DNS interception checks enabled' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DNSInterceptionChecksEnabled" ` + | Select-Object -ExpandProperty "DNSInterceptionChecksEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.76" + Task = "(L1) Ensure 'Enable AutoFill for addresses' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "AutofillAddressEnabled" ` + | Select-Object -ExpandProperty "AutofillAddressEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.77" + Task = "(L1) Ensure 'Enable AutoFill for payment instructions' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "AutofillCreditCardEnabled" ` + | Select-Object -ExpandProperty "AutofillCreditCardEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.78" + Task = "(L1) Ensure 'Enable browser legacy extension point blocking' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "BrowserLegacyExtensionPointsBlockingEnabled" ` + | Select-Object -ExpandProperty "BrowserLegacyExtensionPointsBlockingEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.79" + Task = "(L1) Ensure 'Enable component updates in Microsoft Edge' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ComponentUpdatesEnabled" ` + | Select-Object -ExpandProperty "ComponentUpdatesEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.80" + Task = "(L1) Ensure 'Enable CryptoWallet feature' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "CryptoWalletEnabled" ` + | Select-Object -ExpandProperty "CryptoWalletEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.81" + Task = "(L1) Ensure 'Enable deleting browser and download history' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "AllowDeletingBrowserHistory" ` + | Select-Object -ExpandProperty "AllowDeletingBrowserHistory" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.82" + Task = "(L1) Ensure 'Enable Discover access to page contents for AAD profiles' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DiscoverPageContextenabled" ` + | Select-Object -ExpandProperty "DiscoverPageContextenabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.83" + Task = "(L2) Ensure 'Enable Drop feature in Microsoft Edge' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "EdgeEdropenabled" ` + | Select-Object -ExpandProperty "EdgeEdropenabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.84" + Task = "(L1) Ensure 'Enable Follow service in Microsoft Edge' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "EdgeFollowEnabled" ` + | Select-Object -ExpandProperty "EdgeFollowEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.85" + Task = "(L1) Ensure 'Enable globally scoped HTTP auth cache' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "GloballyScopeHTTPAuthCacheEnabled" ` + | Select-Object -ExpandProperty "GloballyScopeHTTPAuthCacheEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.86" + Task = "(L2) Ensure 'Enable guest mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "BrowserGuestModeEnabled" ` + | Select-Object -ExpandProperty "BrowserGuestModeEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.87" + Task = "(L1) Ensure 'Enable network prediction' is set to 'Enabled: Don't predict network actions on any network connection'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "NetworkPredictionOptions" ` + | Select-Object -ExpandProperty "NetworkPredictionOptions" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.88" + Task = "(L1) Ensure 'Enable profile creation from the Identity flyout menu or the Settings page' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "BrowserAddProfileEnabled" ` + | Select-Object -ExpandProperty "BrowserAddProfileEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.89" + Task = "(L1) Ensure 'Enable renderer code integrity' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "RendererCodeIntegrityEnabled" ` + | Select-Object -ExpandProperty "RendererCodeIntegrityEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.90" + Task = "(L1) Ensure 'Enable resolution of navigation errors using a web service' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ResolveNavigationErrorsUseWebService" ` + | Select-Object -ExpandProperty "ResolveNavigationErrorsUseWebService" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.91" + Task = "(L2) Ensure 'Enable Search suggestions' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "SearchSuggestEnabled" ` + | Select-Object -ExpandProperty "SearchSuggestEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.92" + Task = "(L1) Ensure 'Enable security warnings for command-line flags' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "CommandLineFlagSecurityWarningsEnabled" ` + | Select-Object -ExpandProperty "CommandLineFlagSecurityWarningsEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.93" + Task = "(L1) Ensure 'Enable site isolation for every site' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "SitePerProcess" ` + | Select-Object -ExpandProperty "SitePerProcess" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.94" + Task = "(L2) Ensure 'Enable Translate' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "TranslateEnabled" ` + | Select-Object -ExpandProperty "TranslateEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.95" + Task = "(L1) Ensure 'Enable use of ephemeral profiles' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ForceEphemeralProfiles" ` + | Select-Object -ExpandProperty "ForceEphemeralProfiles" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.96" + Task = "(L1) Ensure 'Enable warnings for insecure forms' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "InsecureFormsWarningsEnabled" ` + | Select-Object -ExpandProperty "InsecureFormsWarningsEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.97" + Task = "(L2) Ensure 'Enforce Bing SafeSearch' is set to 'Enabled: Configure moderate search restrictions in Bing'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ForceBingSafeSearch" ` + | Select-Object -ExpandProperty "ForceBingSafeSearch" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.98" + Task = "(L2) Ensure 'Enforce Google SafeSearch' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ForceGoogleSafeSearch" ` + | Select-Object -ExpandProperty "ForceGoogleSafeSearch" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.99" + Task = "(L1) Ensure 'Enhance the security state in Microsoft Edge' is set to 'Enabled: Balanced mode'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "EnhanceSecurityMode" ` + | Select-Object -ExpandProperty "EnhanceSecurityMode" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.100" + Task = "(L2) Ensure 'Enhanced Security Mode configuration for Intranet zone sites' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "EnhanceSecurityModeBypassIntranet" ` + | Select-Object -ExpandProperty "EnhanceSecurityModeBypassIntranet" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.101" + Task = "(L1) Ensure 'Hide the First-run experience and splash screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "HideFirstRunExperience" ` + | Select-Object -ExpandProperty "HideFirstRunExperience" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.102" + Task = "(L1) Ensure 'In-app support Enabled' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "InAppSupportEnabled" ` + | Select-Object -ExpandProperty "InAppSupportEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.103" + Task = "(L2) Ensure 'Let users snip a Math problem and get the solution with a step-by-step explanation in Microsoft Edge' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "MathSolverEnabled" ` + | Select-Object -ExpandProperty "MathSolverEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.104" + Task = "(L2) Ensure 'Live captions allowed' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "LiveCaptionsAllowed" ` + | Select-Object -ExpandProperty "LiveCaptionsAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.105" + Task = "(L1) Ensure 'Manage exposure of local IP addresses by WebRTC' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\WebRtcLocalIpsAllowedUrls" ` + -Name "Default" ` + | Select-Object -ExpandProperty "Default" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.106" + Task = "(L1) Ensure 'Notify a user that a browser restart is recommended or required for pending updates' is set to 'Enabled: Required - Show a recurring prompt to the user indicating that a restart is required'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "RelaunchNotification" ` + | Select-Object -ExpandProperty "RelaunchNotification" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.107" + Task = "(L1) Ensure 'Restrict exposure of local IP address by WebRTC' is set to 'Enabled: Allow public interface over http default route. This doesn't expose the local IP address'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "WebRtcLocalhostIpHandling" ` + | Select-Object -ExpandProperty "WebRtcLocalhostIpHandling" + + if ($regValue -ne "default_public_interface_only") { + return @{ + Message = "Registry value is '$regValue'. Expected: default_public_interface_only" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.108" + Task = "(L1) Ensure 'Set disk cache size, in bytes' is set to 'Enabled: 250609664'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DiskCacheSize" ` + | Select-Object -ExpandProperty "DiskCacheSize" + + if (($regValue -ne 250609664)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 250609664" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.109" + Task = "(L1) Ensure 'Set the time period for update notifications' is set to 'Enabled: 86400000'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "RelaunchNotificationPeriod" ` + | Select-Object -ExpandProperty "RelaunchNotificationPeriod" + + if (($regValue -ne 86400000)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 86400000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.110" + Task = "(L1) Ensure 'Shopping in Microsoft Edge Enabled' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "EdgeShoppingAssistantEnabled" ` + | Select-Object -ExpandProperty "EdgeShoppingAssistantEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.111" + Task = "(L2) Ensure 'Show an `"Always open`" checkbox in external protocol dialog' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ExternalProtocolDialogShowAlwaysOpenCheckbox" ` + | Select-Object -ExpandProperty "ExternalProtocolDialogShowAlwaysOpenCheckbox" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.112" + Task = "(L1) Ensure 'Show Microsoft Rewards experiences' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "ShowMicrosoftRewards" ` + | Select-Object -ExpandProperty "ShowMicrosoftRewards" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.113" + Task = "(L1) Ensure 'Show the Reload in Internet Explorer mode button in the toolbar' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "InternetExplorerModeToolbarButtonEnabled" ` + | Select-Object -ExpandProperty "InternetExplorerModeToolbarButtonEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.114" + Task = "(L1) Ensure 'Specifies whether SharedArrayBuffers can be used in a non cross-origin-isolated context' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "SharedArrayBufferUnrestrictedAccessAllowed" ` + | Select-Object -ExpandProperty "SharedArrayBufferUnrestrictedAccessAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.115" + Task = "(L2) Ensure 'Specify if online OCSP/CRL checks are required for local trust anchors' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "RequireOnlineRevocationChecksForLocalAnchors" ` + | Select-Object -ExpandProperty "RequireOnlineRevocationChecksForLocalAnchors" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.116" + Task = "(L2) Ensure 'Spell checking provided by Microsoft Editor' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "MicrosoftEditorProofingEnabled" ` + | Select-Object -ExpandProperty "MicrosoftEditorProofingEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.117" + Task = "(L1) Ensure 'Standalone Sidebar Enabled' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "StandaloneHubsSidebarEnabled" ` + | Select-Object -ExpandProperty "StandaloneHubsSidebarEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.118" + Task = "(L1) Ensure 'Suggest similar pages when a webpage can’t be found' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "AlternateErrorPagesEnabled" ` + | Select-Object -ExpandProperty "AlternateErrorPagesEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.119" + Task = "(L1) Ensure 'Suppress the unsupported OS warning' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "SuppressUnsupportedOSWarning" ` + | Select-Object -ExpandProperty "SuppressUnsupportedOSWarning" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.120" + Task = "(L2) Ensure 'Tab Services enabled' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "TabservicesEnabled" ` + | Select-Object -ExpandProperty "TabservicesEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.121" + Task = "(L2) Ensure 'Text prediction enabled by default' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "TextPredictionEnabled" ` + | Select-Object -ExpandProperty "TextPredictionEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.122" + Task = "(L1) Ensure 'Wait for Internet Explorer mode tabs to completely unload before ending the browser session' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "InternetExplorerIntegrationAlwayswaitForUnload" ` + | Select-Object -ExpandProperty "InternetExplorerIntegrationAlwayswaitForUnload" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.1.1" + Task = "(L1) Ensure 'Update policy override default' is set to 'Enabled: Always allow updates (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\EdgeUpdate" ` + -Name "UpdateDefault" ` + | Select-Object -ExpandProperty "UpdateDefault" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.3.1" + Task = "(L1) Ensure 'Auto-update check period override' is set to any value except '0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\EdgeUpdate" ` + -Name "AutoUpdateCheckPeriodMinutes" ` + | Select-Object -ExpandProperty "AutoUpdateCheckPeriodMinutes" + + if (($regValue -lt 1 -and $regValue -gt 43200)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x > 0 and x <= 43200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Edge-Microsoft-117#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Edge-Microsoft-117#RegistrySettings.ps1 new file mode 100644 index 0000000..cc37be1 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Edge-Microsoft-117#RegistrySettings.ps1 @@ -0,0 +1,684 @@ +[AuditTest] @{ + Id = "1.1.1" + Task = "Ensure 'Enable site isolation for every site' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "SitePerProcess" ` + | Select-Object -ExpandProperty "SitePerProcess" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "Ensure 'Supported authentication schemes' is set to 'ntlm, negotiate'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "AuthSchemes" ` + | Select-Object -ExpandProperty "AuthSchemes" + + if ($regValue -notmatch "^(ntlm\s*,\s*negotiate|negotiate\s*,\s*ntlm)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: ntlm, negotiate" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "Ensure 'Allow user-level native messaging hosts (installed without admin permissions)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "NativeMessagingUserLevelHosts" ` + | Select-Object -ExpandProperty "NativeMessagingUserLevelHosts" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "Ensure 'Configure Microsoft Defender SmartScreen' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "SmartScreenEnabled" ` + | Select-Object -ExpandProperty "SmartScreenEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.5" + Task = "Ensure 'Prevent bypassing Microsoft Defender SmartScreen prompts for sites' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "PreventSmartScreenPromptOverride" ` + | Select-Object -ExpandProperty "PreventSmartScreenPromptOverride" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.6" + Task = "Ensure 'Prevent bypassing of Microsoft Defender SmartScreen warnings about downloads' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "PreventSmartScreenPromptOverrideForFiles" ` + | Select-Object -ExpandProperty "PreventSmartScreenPromptOverrideForFiles" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.7" + Task = "Ensure 'Allow users to proceed from the HTTPS warning page' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "SSLErrorOverrideAllowed" ` + | Select-Object -ExpandProperty "SSLErrorOverrideAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.8" + Task = "Ensure 'Configure Microsoft Defender SmartScreen to block potentially unwanted apps' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "SmartScreenPuaEnabled" ` + | Select-Object -ExpandProperty "SmartScreenPuaEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.9" + Task = "Ensure 'Allow Basic authentication for HTTP' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "BasicAuthOverHttpEnabled" ` + | Select-Object -ExpandProperty "BasicAuthOverHttpEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.10" + Task = "Ensure 'Allow unconfigured sites to be reloaded in Internet Explorer mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "InternetExplorerIntegrationReloadInIEModeAllowed" ` + | Select-Object -ExpandProperty "InternetExplorerIntegrationReloadInIEModeAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.11" + Task = "Ensure 'Specifies whether SharedArrayBuffers can be used in a non cross-origin-isolated context' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "SharedArrayBufferUnrestrictedAccessAllowed" ` + | Select-Object -ExpandProperty "SharedArrayBufferUnrestrictedAccessAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.12" + Task = "Ensure 'Specifies whether to allow websites to make requests to more-private network endpoints' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "InsecurePrivateNetworkRequestsAllowed" ` + | Select-Object -ExpandProperty "InsecurePrivateNetworkRequestsAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.13" + Task = "Ensure 'Enable browser legacy extension point blocking' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "BrowserLegacyExtensionPointsBlockingEnabled" ` + | Select-Object -ExpandProperty "BrowserLegacyExtensionPointsBlockingEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.14" + Task = "Ensure 'Show the Reload in Internet Explorer mode button in the toolbar' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "InternetExplorerModeToolbarButtonEnabled" ` + | Select-Object -ExpandProperty "InternetExplorerModeToolbarButtonEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.15" + Task = "Ensure 'Configure Edge TyposquattingChecker' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "TyposquattingCheckerEnabled" ` + | Select-Object -ExpandProperty "TyposquattingCheckerEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.16" + Task = "Ensure 'Enhance images enabled' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "EdgeEnhanceImagesEnabled" ` + | Select-Object -ExpandProperty "EdgeEnhanceImagesEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.17" + Task = "Ensure 'Force WebSQL to be enabled' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "WebSQLAccess" ` + | Select-Object -ExpandProperty "WebSQLAccess" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.18" + Task = "Ensure 'Automatically open downloaded MHT or MHTML files from the web in Internet Explorer mode' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "InternetExplorerIntegrationZoneIdentifierMhtFileAllowed" ` + | Select-Object -ExpandProperty "InternetExplorerIntegrationZoneIdentifierMhtFileAllowed" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.20" + Task = "Block all extensions not on allow list" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge\ExtensionInstallBlocklist" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "*") { + return @{ + Message = "Registry value is '$regValue'. Expected: *" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Internet Explorer 11-CIS-1.0.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Internet Explorer 11-CIS-1.0.0#RegistrySettings.ps1 new file mode 100644 index 0000000..7962c4b --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Internet Explorer 11-CIS-1.0.0#RegistrySettings.ps1 @@ -0,0 +1,5650 @@ +[AuditTest] @{ + Id = "1.1" + Task = "Set 'Turn on Enhanced Protected Mode' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation" ` + | Select-Object -ExpandProperty "Isolation" + + if ($regValue -ne "PMEM") { + return @{ + Message = "Registry value is '$regValue'. Expected: PMEM" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2" + Task = "Set 'Allow software to run or install even if the signature is invalid' to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "RunInvalidSignatures" ` + | Select-Object -ExpandProperty "RunInvalidSignatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3" + Task = "Set 'Prevent Bypassing SmartScreen Filter Warnings' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.4" + Task = "Set 'Prevent bypassing SmartScreen Filter warnings about files that are not commonly downloaded from the Internet' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverrideAppRepUnknown" ` + | Select-Object -ExpandProperty "PreventOverrideAppRepUnknown" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.5" + Task = "Configure 'Do not allow users to enable or disable add-ons'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Restrictions" ` + -Name "NoExtensionManagement" ` + | Select-Object -ExpandProperty "NoExtensionManagement" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.6" + Task = "Set 'Disable Save this program to disk option' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Restrictions" ` + -Name "NoSelectDownloadDir" ` + | Select-Object -ExpandProperty "NoSelectDownloadDir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.1" + Task = "Set 'Prevent per-user installation of ActiveX controls' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security\ActiveX" ` + -Name "BlockNonAdminActiveXInstall" ` + | Select-Object -ExpandProperty "BlockNonAdminActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.2" + Task = "Set 'Specify use of ActiveX Installer Service for installation of ActiveX controls' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AxInstaller" ` + -Name "OnlyUseAXISForActiveXInstall" ` + | Select-Object -ExpandProperty "OnlyUseAXISForActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3" + Task = "Set 'Turn on ActiveX Filtering' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Safety\ActiveXFiltering" ` + -Name "IsEnabled" ` + | Select-Object -ExpandProperty "IsEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.4" + Task = "Set 'Turn off ActiveX opt-in prompt' to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "NoFirsttimeprompt" ` + | Select-Object -ExpandProperty "NoFirsttimeprompt" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.5" + Task = "Set 'Do not allow ActiveX controls to run in Protected Mode when Enhanced Protected Mode is enabled' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "DisableEPMCompat" ` + | Select-Object -ExpandProperty "DisableEPMCompat" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.1" + Task = "Configure 'Prevent deleting websites that the user has visited'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Privacy" ` + -Name "CleanHistory" ` + | Select-Object -ExpandProperty "CleanHistory" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.2" + Task = "Configure 'Prevent Deleting Cookies'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Privacy" ` + -Name "CleanCookies" ` + | Select-Object -ExpandProperty "CleanCookies" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.3" + Task = "Set 'Disable `"Configuring History`"' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "History" ` + | Select-Object -ExpandProperty "History" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.4" + Task = "Set 'Days to keep pages in History' to '40'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Url History" ` + -Name "DaysToKeep" ` + | Select-Object -ExpandProperty "DaysToKeep" + + if (($regValue -lt 40)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 40" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.5" + Task = "Configure 'Prevent Deleting Temporary Internet Files'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Privacy" ` + -Name "CleanTIF" ` + | Select-Object -ExpandProperty "CleanTIF" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.6" + Task = "Configure 'Allow deleting browsing history on exit'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Privacy" ` + -Name "CleanBrowsingHistoryOnExit" ` + | Select-Object -ExpandProperty "CleanBrowsingHistoryOnExit" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.7" + Task = "Set 'Prevent access to Delete Browsing History' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "DisableDeleteBrowsingHistory" ` + | Select-Object -ExpandProperty "DisableDeleteBrowsingHistory" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.8" + Task = "Configure 'Turn off InPrivate Browsing'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Privacy" ` + -Name "EnableInPrivateBrowsing" ` + | Select-Object -ExpandProperty "EnableInPrivateBrowsing" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.1" + Task = "Configure 'URL to be displayed for updates:'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Update_Check_Page" ` + | Select-Object -ExpandProperty "Update_Check_Page" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.2" + Task = "Set 'Update check interval (in days):' to 'Enabled:30'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Update_Check_Interval" ` + | Select-Object -ExpandProperty "Update_Check_Interval" + + if ($regValue -ne 30) { + return @{ + Message = "Registry value is '$regValue'. Expected: 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.3" + Task = "Configure 'Automatically check for Internet Explorer updates'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "NoUpdateCheck" ` + | Select-Object -ExpandProperty "NoUpdateCheck" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.4" + Task = "Configure 'Install new versions of Internet Explorer automatically'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "EnableAutoUpgrade" ` + | Select-Object -ExpandProperty "EnableAutoUpgrade" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1" + Task = "Set 'Turn off Encryption Support' to 'Use TLS 1.1 and TLS 1.2'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "SecureProtocols" ` + | Select-Object -ExpandProperty "SecureProtocols" + + if ($regValue -ne 2560) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2560" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2" + Task = "Set 'Check for server certificate revocation' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "CertificateRevocation" ` + | Select-Object -ExpandProperty "CertificateRevocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.3" + Task = "Set 'Check for signatures on downloaded programs' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "CheckExeSignatures" ` + | Select-Object -ExpandProperty "CheckExeSignatures" + + if ($regValue -ne "yes") { + return @{ + Message = "Registry value is '$regValue'. Expected: yes" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.4" + Task = "Set 'Turn on certificate address mismatch warning' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "WarnOnBadCertRecving" ` + | Select-Object -ExpandProperty "WarnOnBadCertRecving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.5" + Task = "Set 'Prevent ignoring certificate errors' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "PreventIgnoreCertErrors" ` + | Select-Object -ExpandProperty "PreventIgnoreCertErrors" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.6" + Task = "Set 'Disable changing certificate settings' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "Certificates" ` + | Select-Object -ExpandProperty "Certificates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "6.1" + Task = "Set 'Turn off browser geolocation' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Geolocation" ` + -Name "PolicyDisableGeolocation" ` + | Select-Object -ExpandProperty "PolicyDisableGeolocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "6.2" + Task = "Configure 'Turn off URL Suggestions'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\DomainSuggestion" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "6.3" + Task = "Configure 'Prevent participation in the Customer Experience Improvement Program'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\SQM" ` + -Name "DisableCustomerImprovementProgram" ` + | Select-Object -ExpandProperty "DisableCustomerImprovementProgram" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "6.4" + Task = "Configure 'Turn on Suggested Sites'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Suggested Sites" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "7.1" + Task = "Set 'Restrict ActiveX Install' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "iexplorer.exe" ` + | Select-Object -ExpandProperty "iexplorer.exe" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "7.2" + Task = "Set 'Scripted Window Security Restrictions' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "7.3" + Task = "Set 'Mime Sniffing Safety Feature' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "7.4" + Task = "Set 'Notification bar' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "7.5" + Task = "Set 'MK Protocol Security Restriction' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "iexplorer.exe" ` + | Select-Object -ExpandProperty "iexplorer.exe" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "7.6" + Task = "Set 'Consistent Mime Handling' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "7.7" + Task = "Set 'Restrict File Download' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "iexplorer.exe" ` + | Select-Object -ExpandProperty "iexplorer.exe" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "7.8" + Task = "Set 'Protection From Zone Elevation' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.1" + Task = "Set 'Java permissions' to 'Enabled:Disable Java'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.2" + Task = "Set 'Allow paste operations via script' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.3" + Task = "Set 'Protected Mode' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.4" + Task = "Set 'Turn on Cross-Site Scripting (XSS) Filter' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.5" + Task = "Set 'Run .NET Framework-reliant components signed with Authenticode' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.6" + Task = "Set 'Use Pop-up Blocker' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.7" + Task = "Set 'Scriptlets' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.8" + Task = "Set 'Only allow approved domains to use ActiveX controls without prompt' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.9" + Task = "Set 'Allow drag and drop or copy and paste files' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.10" + Task = "Set 'Run .NET Framework-reliant components not signed with Authenticode' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.11" + Task = "Set 'Internet Explorer web browser control' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.12" + Task = "Set 'Download unsigned ActiveX controls' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.13" + Task = "Set 'Download signed ActiveX controls' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.14" + Task = "Set 'Allow font downloads' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1604" ` + | Select-Object -ExpandProperty "1604" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.15" + Task = "Set 'Launching programs and unsafe files' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.16" + Task = "Set 'Automatic prompting for file downloads' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.17" + Task = "Set 'Allow installation of desktop items' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1800" ` + | Select-Object -ExpandProperty "1800" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.18" + Task = "Set 'XAML Files' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.19" + Task = "Set 'Initialize and script ActiveX controls not marked as safe' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.20" + Task = "Set 'Enable MIME Sniffing' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2100" ` + | Select-Object -ExpandProperty "2100" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.21" + Task = "Set 'Logon options' to 'Enabled:Prompt for user name and password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.22" + Task = "Set 'Access data sources across domains' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.23" + Task = "Set 'Status bar updates via script' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.24" + Task = "Set 'Include local directory path when uploading files to a server' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.25" + Task = "Set 'Userdata persistence' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.26" + Task = "Set 'Enable dragging of content from different domains within a window' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.27" + Task = "Set 'Navigate windows and frames across different domains' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.28" + Task = "Set 'Enable dragging of content from different domains across windows' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.29" + Task = "Set 'Allow script-initiated windows without size or position constraints' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.30" + Task = "Set 'Launching applications and files in an IFRAME' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.31" + Task = "Set 'Software channel permissions' to 'Enabled:High safety'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1E05" ` + | Select-Object -ExpandProperty "1E05" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.32" + Task = "Configure 'First-Run Opt-In'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1208" ` + | Select-Object -ExpandProperty "1208" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.33" + Task = "Set 'Web sites in less privileged Web content zones can navigate into this zone' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1.34" + Task = "Set 'Don't run antimalware programs against ActiveX controls' to 'Enabled:Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.2.1" + Task = "Set 'Java permissions' to 'Enabled:High safety'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.2.2" + Task = "Set 'Initialize and script ActiveX controls not marked as safe' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.2.3" + Task = "Set 'Intranet Sites: Include all network paths (UNCs)' to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap" ` + -Name "UNCAsIntranet" ` + | Select-Object -ExpandProperty "UNCAsIntranet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.2.4" + Task = "Set 'Don't run antimalware programs against ActiveX controls' to 'Enabled:Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.1" + Task = "Set 'Java permissions' to 'Enabled:Disable Java'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.2" + Task = "Set 'Allow drag and drop or copy and paste files' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.3" + Task = "Set 'Download signed ActiveX controls' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.4" + Task = "Set 'Script ActiveX controls marked safe for scripting' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1405" ` + | Select-Object -ExpandProperty "1405" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.5" + Task = "Set 'Allow active scripting' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1400" ` + | Select-Object -ExpandProperty "1400" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.6" + Task = "Set 'Turn on Cross-Site Scripting (XSS) Filter' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.7" + Task = "Set 'Initialize and script ActiveX controls not marked as safe' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.8" + Task = "Set 'Run .NET Framework-reliant components signed with Authenticode' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.9" + Task = "Set 'Allow paste operations via script' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.10" + Task = "Set 'Protected Mode' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.11" + Task = "Set 'Allow installation of desktop items' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1800" ` + | Select-Object -ExpandProperty "1800" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.12" + Task = "Set 'Launching programs and unsafe files' to 'Enabled:Prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.13" + Task = "Set 'Automatic prompting for file downloads' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.14" + Task = "Set 'XAML Files' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.15" + Task = "Set 'Allow font downloads' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1604" ` + | Select-Object -ExpandProperty "1604" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.16" + Task = "Set 'Enable MIME Sniffing' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2100" ` + | Select-Object -ExpandProperty "2100" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.17" + Task = "Set 'Internet Explorer web browser control' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.18" + Task = "Set 'Allow Binary and Script Behaviors' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2000" ` + | Select-Object -ExpandProperty "2000" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.19" + Task = "Set 'Scripting of Java applets' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1402" ` + | Select-Object -ExpandProperty "1402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.20" + Task = "Set 'Use Pop-up Blocker' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.21" + Task = "Set 'Download unsigned ActiveX controls' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.22" + Task = "Set 'Scriptlets' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.23" + Task = "Set 'Allow file downloads' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1803" ` + | Select-Object -ExpandProperty "1803" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.24" + Task = "Set 'Only allow approved domains to use ActiveX controls without prompt' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.25" + Task = "Set 'Use SmartScreen Filter' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.26" + Task = "Set 'Run ActiveX controls and plugins' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1200" ` + | Select-Object -ExpandProperty "1200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.27" + Task = "Set 'Run .NET Framework-reliant components not signed with Authenticode' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.28" + Task = "Set 'Logon options' to 'Enabled:Anonymous logon'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.29" + Task = "Set 'Allow script-initiated windows without size or position constraints' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.30" + Task = "Set 'Allow META REFRESH' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1608" ` + | Select-Object -ExpandProperty "1608" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.31" + Task = "Set 'Userdata persistence' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.32" + Task = "Set 'Navigate windows and frames across different domains' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.33" + Task = "Set 'Software channel permissions' to 'Enabled:High safety'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1E05" ` + | Select-Object -ExpandProperty "1E05" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.34" + Task = "Set 'Include local directory path when uploading files to a server' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.35" + Task = "Set 'Enable dragging of content from different domains within a window' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.36" + Task = "Set 'Status bar updates via script' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.37" + Task = "Set 'Access data sources across domains' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.38" + Task = "Set 'Web sites in less privileged Web content zones can navigate into this zone' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.39" + Task = "Configure 'First-Run Opt-In'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1208" ` + | Select-Object -ExpandProperty "1208" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.40" + Task = "Set 'Enable dragging of content from different domains across windows' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.41" + Task = "Set 'Launching applications and files in an IFRAME' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.3.42" + Task = "Set 'Don't run antimalware programs against ActiveX controls' to 'Enabled:Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.4.1" + Task = "Set 'Java permissions' to 'Enabled:Disable Java'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.4.2" + Task = "Set 'Use SmartScreen Filter' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.4.3" + Task = "Set 'Don't run antimalware programs against ActiveX controls' to 'Enabled:Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.5.1" + Task = "Set 'Java permissions' to 'Enabled:High safety'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.5.2" + Task = "Set 'Initialize and script ActiveX controls not marked as safe' to 'Enabled:Disable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.5.3" + Task = "Set 'Don't run antimalware programs against ActiveX controls' to 'Enabled:Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.6.1" + Task = "Set 'Use SmartScreen Filter' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\3" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.6.2" + Task = "Set 'Only allow approved domains to use ActiveX controls without prompt' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\3" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.7.1" + Task = "Set 'Java permissions' to 'Enabled:Disable Java'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.7.2" + Task = "Set 'Use SmartScreen Filter' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\1" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.8.1" + Task = "Set 'Java permissions' to 'Enabled:Disable Java'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.8.2" + Task = "Set 'Only allow approved domains to use ActiveX controls without prompt' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.8.3" + Task = "Set 'Use SmartScreen Filter' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.9.1" + Task = "Set 'Java permissions' to 'Enabled:Disable Java'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.9.2" + Task = "Set 'Use SmartScreen Filter' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\0" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.10.1" + Task = "Set 'Java permissions' to 'Enabled:Disable Java'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.10.2" + Task = "Set 'Use SmartScreen Filter' to 'Enabled:Enable'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\2" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.11" + Task = "Set 'Security Zones: Do not allow users to change policies' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_options_edit" ` + | Select-Object -ExpandProperty "Security_options_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.12" + Task = "Set 'Security Zones: Do not allow users to add/delete sites' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_zones_map_edit" ` + | Select-Object -ExpandProperty "Security_zones_map_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.13" + Task = "Set 'Security Zones: Use only machine settings' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_HKLM_only" ` + | Select-Object -ExpandProperty "Security_HKLM_only" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.1" + Task = "Set 'Disable the Security page' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "SecurityTab" ` + | Select-Object -ExpandProperty "SecurityTab" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.2" + Task = "Set 'Disable the Advanced page' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "AdvancedTab" ` + | Select-Object -ExpandProperty "AdvancedTab" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.3" + Task = "Set 'Prevent downloading of enclosures' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.4" + Task = "Set 'Turn on Basic feed authentication over HTTP' to 'Not Configured'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "AllowBasicAuthInClear" ` + | Select-Object -ExpandProperty "AllowBasicAuthInClear" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.5" + Task = "Configure 'Make proxy settings per-machine (rather than per-user)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "ProxySettingsPerUser" ` + | Select-Object -ExpandProperty "ProxySettingsPerUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.6" + Task = "Configure 'Do not display the reveal password button'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.7" + Task = "Set 'Prevent changing proxy settings' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "Proxy" ` + | Select-Object -ExpandProperty "Proxy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.8" + Task = "Configure 'Disable changing Automatic Configuration settings'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "Autoconfig" ` + | Select-Object -ExpandProperty "Autoconfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.9" + Task = "Set 'Prevent `"Fix settings`" functionality' to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security" ` + -Name "DisableFixSecuritySettings" ` + | Select-Object -ExpandProperty "DisableFixSecuritySettings" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.10" + Task = "Set 'Turn off the Security Settings Check feature' to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security" ` + -Name "DisableSecuritySettingsCheck" ` + | Select-Object -ExpandProperty "DisableSecuritySettingsCheck" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.11_1" + Task = "Configure 'Disable changing connection settings'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "ProxySettingsPerUser" ` + | Select-Object -ExpandProperty "ProxySettingsPerUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.11_2" + Task = "Configure 'Disable changing connection settings'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "Proxy" ` + | Select-Object -ExpandProperty "Proxy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.12" + Task = "Set 'Turn off Crash Detection' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Restrictions" ` + -Name "NoCrashDetection" ` + | Select-Object -ExpandProperty "NoCrashDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.13" + Task = "Set 'Disable AutoComplete for forms' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "FormSuggest" ` + | Select-Object -ExpandProperty "FormSuggest" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.14" + Task = "Set 'Turn on the auto-complete feature for user names and passwords on forms' to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "FormSuggest Passwords" ` + | Select-Object -ExpandProperty "FormSuggest Passwords" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.15" + Task = "Set 'Turn on 64-bit tab processes when running in Enhanced Protected Mode on 64-bit versions of Windows' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation64Bit" ` + | Select-Object -ExpandProperty "Isolation64Bit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Internet Explorer 11-DISA-V1R16#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Internet Explorer 11-DISA-V1R16#RegistrySettings.ps1 new file mode 100644 index 0000000..0f15a10 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Internet Explorer 11-DISA-V1R16#RegistrySettings.ps1 @@ -0,0 +1,4968 @@ +[AuditTest] @{ + Id = "DTBI014-IE11" + Task = "Turn off Encryption Support must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "SecureProtocols" ` + | Select-Object -ExpandProperty "SecureProtocols" + + if ($regValue -ne 2560) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2560" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI015-IE11" + Task = "The Internet Explorer warning about certificate address mismatch must be enforced." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "WarnOnBadCertRecving" ` + | Select-Object -ExpandProperty "WarnOnBadCertRecving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI018-IE11" + Task = "Check for publishers certificate revocation must be enforced." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\WinTrust\Trust Providers\Software Publishing" ` + -Name "State" ` + | Select-Object -ExpandProperty "State" + + if ($regValue -ne 146432) { + return @{ + Message = "Registry value is '$regValue'. Expected: 146432" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI022-IE11" + Task = "The Download signed ActiveX controls property must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI023-IE11" + Task = "The Download unsigned ActiveX controls property must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI024-IE11" + Task = "The Initialize and script ActiveX controls not marked as safe property must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI030-IE11" + Task = "Font downloads must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1604" ` + | Select-Object -ExpandProperty "1604" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI031-IE11" + Task = "The Java permissions must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI032-IE11" + Task = "Accessing data sources across domains must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI036-IE11" + Task = "Functionality to drag and drop or copy and paste files must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI038-IE11" + Task = "Launching programs and files in IFRAME must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI039-IE11" + Task = "Navigating windows and frames across different domains must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI042-IE11" + Task = "Userdata persistence must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI044-IE11" + Task = "Clipboard operations via script must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI046-IE11" + Task = "Logon options must be configured to prompt (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI061-IE11" + Task = "Java permissions must be configured with High Safety (Intranet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI091-IE11" + Task = "Java permissions must be configured with High Safety (Trusted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1000-IE11" + Task = "Dragging of content from different domains within a window must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1005-IE11" + Task = "Dragging of content from different domains across windows must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1010-IE11" + Task = "Internet Explorer Processes Restrict ActiveX Install must be enforced (Explorer)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1020-IE11" + Task = "Internet Explorer Processes Restrict ActiveX Install must be enforced (iexplore)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1025-IE11" + Task = "Dragging of content from different domains within a window must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI112-IE11" + Task = "The Download signed ActiveX controls property must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI113-IE11" + Task = "The Download unsigned ActiveX controls property must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI114-IE11" + Task = "The Initialize and script ActiveX controls not marked as safe property must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI115-IE11" + Task = "ActiveX controls and plug-ins must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1200" ` + | Select-Object -ExpandProperty "1200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI116-IE11" + Task = "ActiveX controls marked safe for scripting must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1405" ` + | Select-Object -ExpandProperty "1405" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI119-IE11" + Task = "File downloads must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1803" ` + | Select-Object -ExpandProperty "1803" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI120-IE11" + Task = "Font downloads must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1604" ` + | Select-Object -ExpandProperty "1604" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI121-IE11" + Task = "Java permissions must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI122-IE11" + Task = "Accessing data sources across domains must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI123-IE11" + Task = "The Allow META REFRESH property must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1608" ` + | Select-Object -ExpandProperty "1608" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI126-IE11" + Task = "Functionality to drag and drop or copy and paste files must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI128-IE11" + Task = "Launching programs and files in IFRAME must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI129-IE11" + Task = "Navigating windows and frames across different domains must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI132-IE11" + Task = "Userdata persistence must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI133-IE11" + Task = "Active scripting must be disallowed (Restricted Sites Zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1400" ` + | Select-Object -ExpandProperty "1400" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI134-IE11" + Task = "Clipboard operations via script must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI136-IE11" + Task = "Logon options must be configured and enforced (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI300-IE11" + Task = "Configuring History setting must be set to 40 days." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Url History" ` + -Name "DaysToKeep" ` + | Select-Object -ExpandProperty "DaysToKeep" + + if ($regValue -ne 40) { + return @{ + Message = "Registry value is '$regValue'. Expected: 40" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI318-IE11" + Task = "Internet Explorer must be set to disallow users to add/delete sites." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_zones_map_edit" ` + | Select-Object -ExpandProperty "Security_zones_map_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI319-IE11" + Task = "Internet Explorer must be configured to disallow users to change policies." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_options_edit" ` + | Select-Object -ExpandProperty "Security_options_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI320-IE11" + Task = "Internet Explorer must be configured to use machine settings." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_HKLM_only" ` + | Select-Object -ExpandProperty "Security_HKLM_only" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI325-IE11" + Task = "Security checking features must be enforced." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security" ` + -Name "DisableSecuritySettingsCheck" ` + | Select-Object -ExpandProperty "DisableSecuritySettingsCheck" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI350-IE11" + Task = "Software must be disallowed to run or install with invalid signatures." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "RunInvalidSignatures" ` + | Select-Object -ExpandProperty "RunInvalidSignatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI365-IE11" + Task = "Checking for server certificate revocation must be enforced." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "CertificateRevocation" ` + | Select-Object -ExpandProperty "CertificateRevocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI370-IE11" + Task = "Checking for signatures on downloaded programs must be enforced." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "CheckExeSignatures" ` + | Select-Object -ExpandProperty "CheckExeSignatures" + + if ($regValue -ne "yes") { + return @{ + Message = "Registry value is '$regValue'. Expected: yes" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI375-IE11" + Task = "All network paths (UNCs) for Intranet sites must be disallowed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap" ` + -Name "UNCAsIntranet" ` + | Select-Object -ExpandProperty "UNCAsIntranet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI385-IE11" + Task = "Script-initiated windows without size or position constraints must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI390-IE11" + Task = "Script-initiated windows without size or position constraints must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI395-IE11" + Task = "Scriptlets must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI415-IE11" + Task = "Automatic prompting for file downloads must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI425-IE11" + Task = "Java permissions must be disallowed (Local Machine zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI430-IE11" + Task = "Java permissions must be disallowed (Locked Down Local Machine zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI435-IE11" + Task = "Java permissions must be disallowed (Locked Down Intranet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI440-IE11" + Task = "Java permissions must be disallowed (Locked Down Trusted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI450-IE11" + Task = "Java permissions must be disallowed (Locked Down Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI455-IE11" + Task = "XAML files must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI460-IE11" + Task = "XAML files must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI485-IE11" + Task = "Protected Mode must be enforced (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI490-IE11" + Task = "Protected Mode must be enforced (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI495-IE11" + Task = "Pop-up Blocker must be enforced (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI500-IE11" + Task = "Pop-up Blocker must be enforced (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI515-IE11" + Task = "Websites in less privileged web content zones must be prevented from navigating into the Internet zone." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI520-IE11" + Task = "Websites in less privileged web content zones must be prevented from navigating into the Restricted Sites zone." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI575-IE11" + Task = "Allow binary and script behaviors must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2000" ` + | Select-Object -ExpandProperty "2000" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI580-IE11" + Task = "Automatic prompting for file downloads must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI590-IE11" + Task = "Internet Explorer Processes for MIME handling must be enforced. (Reserved)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI592-IE11" + Task = "Internet Explorer Processes for MIME handling must be enforced (Explorer)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI594-IE11" + Task = "Internet Explorer Processes for MIME handling must be enforced (iexplore)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI595-IE11" + Task = "Internet Explorer Processes for MIME sniffing must be enforced (Reserved)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI596-IE11" + Task = "Internet Explorer Processes for MIME sniffing must be enforced (Explorer)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI597-IE11" + Task = "Internet Explorer Processes for MIME sniffing must be enforced (iexplore)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI599-IE11" + Task = "Internet Explorer Processes for MK protocol must be enforced (Reserved)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI600-IE11" + Task = "Internet Explorer Processes for MK protocol must be enforced (Explorer)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI605-IE11" + Task = "Internet Explorer Processes for MK protocol must be enforced (iexplore)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI610-IE11" + Task = "Internet Explorer Processes for Zone Elevation must be enforced (Reserved)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI612-IE11" + Task = "Internet Explorer Processes for Zone Elevation must be enforced (Explorer)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI614-IE11" + Task = "Internet Explorer Processes for Zone Elevation must be enforced (iexplore)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI630-IE11" + Task = "Internet Explorer Processes for Restrict File Download must be enforced (Reserved)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI635-IE11" + Task = "Internet Explorer Processes for Restrict File Download must be enforced (Explorer)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI640-IE11" + Task = "Internet Explorer Processes for Restrict File Download must be enforced (iexplore)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI645-IE11" + Task = "Internet Explorer Processes for restricting pop-up windows must be enforced (Reserved)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI647-IE11" + Task = "Internet Explorer Processes for restricting pop-up windows must be enforced (Explorer)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI649-IE11" + Task = "Internet Explorer Processes for restricting pop-up windows must be enforced (iexplore)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI650-IE11" + Task = ".NET Framework-reliant components not signed with Authenticode must be disallowed to run (Restricted Sites Zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI655-IE11" + Task = ".NET Framework-reliant components signed with Authenticode must be disallowed to run (Restricted Sites Zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI670-IE11" + Task = "Scripting of Java applets must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1402" ` + | Select-Object -ExpandProperty "1402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI690-IE11" + Task = "AutoComplete feature for forms must be disallowed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Use FormSuggest" ` + | Select-Object -ExpandProperty "Use FormSuggest" + + if ($regValue -ne "no") { + return @{ + Message = "Registry value is '$regValue'. Expected: no" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI715-IE11" + Task = "Crash Detection management must be enforced." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Restrictions" ` + -Name "NoCrashDetection" ` + | Select-Object -ExpandProperty "NoCrashDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI725-IE11" + Task = "Turn on the auto-complete feature for user names and passwords on forms must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "FormSuggest PW Ask" ` + | Select-Object -ExpandProperty "FormSuggest PW Ask" + + if ($regValue -ne "no") { + return @{ + Message = "Registry value is '$regValue'. Expected: no" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI740-IE11" + Task = "Managing SmartScreen Filter use must be enforced." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI760-IE11" + Task = "Browser must retain history on exit." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Privacy" ` + -Name "ClearBrowsingHistoryOnExit" ` + | Select-Object -ExpandProperty "ClearBrowsingHistoryOnExit" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI770-IE11" + Task = "Deleting websites that the user has visited must be disallowed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Privacy" ` + -Name "CleanHistory" ` + | Select-Object -ExpandProperty "CleanHistory" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI780-IE11" + Task = "InPrivate Browsing must be disallowed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Privacy" ` + -Name "EnableInPrivateBrowsing" ` + | Select-Object -ExpandProperty "EnableInPrivateBrowsing" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI800-IE11" + Task = "Scripting of Internet Explorer WebBrowser control property must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI810-IE11" + Task = "When uploading files to a server, the local directory path must be excluded (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI815-IE11" + Task = "Internet Explorer Processes for Notification Bars must be enforced (Reserved)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI820-IE11" + Task = "Security Warning for unsafe files must be set to prompt (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI825-IE11" + Task = "Internet Explorer Processes for Notification Bars must be enforced (Explorer)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI830-IE11" + Task = "ActiveX controls without prompt property must be used in approved domains only (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI835-IE11" + Task = "Internet Explorer Processes for Notification Bars must be enforced (iexplore)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI840-IE11" + Task = "Cross-Site Scripting Filter must be enforced (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI850-IE11" + Task = "Scripting of Internet Explorer WebBrowser Control must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI860-IE11" + Task = "When uploading files to a server, the local directory path must be excluded (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI870-IE11" + Task = "Security Warning for unsafe files must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI880-IE11" + Task = "ActiveX controls without prompt property must be used in approved domains only (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI890-IE11" + Task = "Cross-Site Scripting Filter property must be enforced (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI900-IE11" + Task = "Internet Explorer Processes Restrict ActiveX Install must be enforced (Reserved)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI910-IE11" + Task = "Status bar updates via script must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI920-IE11" + Task = ".NET Framework-reliant components not signed with Authenticode must be disallowed to run (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI930-IE11" + Task = ".NET Framework-reliant components signed with Authenticode must be disallowed to run (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI940-IE11" + Task = "Scriptlets must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI950-IE11" + Task = "Status bar updates via script must be disallowed (Restricted Sites zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI985-IE11" + Task = "When Enhanced Protected Mode is enabled, ActiveX controls must be disallowed to run in Protected Mode." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "DisableEPMCompat" ` + | Select-Object -ExpandProperty "DisableEPMCompat" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI990-IE11" + Task = "Dragging of content from different domains across windows must be disallowed (Internet zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI995-IE11" + Task = "Enhanced Protected Mode functionality must be enforced." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation" ` + | Select-Object -ExpandProperty "Isolation" + + if ($regValue -ne "PMEM") { + return @{ + Message = "Registry value is '$regValue'. Expected: PMEM" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI356-IE11" + Task = "The 64-bit tab processes, when running in Enhanced Protected Mode on 64-bit versions of Windows, must be turned on." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation64Bit" ` + | Select-Object -ExpandProperty "Isolation64Bit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1046-IE11" + Task = "Anti-Malware programs against ActiveX controls must be run for the Internet zone." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI062-IE11" + Task = "Anti-Malware programs against ActiveX controls must be run for the Intranet zone." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI426-IE11" + Task = "Anti-Malware programs against ActiveX controls must be run for the Local Machine zone." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1051-IE11" + Task = "Anti-Malware programs against ActiveX controls must be run for the Restricted Sites zone." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI092-IE11" + Task = "Anti-Malware programs against ActiveX controls must be run for the Trusted Sites zone." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1060-IE11" + Task = "Prevent bypassing SmartScreen Filter warnings must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1065-IE11" + Task = "Prevent bypassing SmartScreen Filter warnings about files that are not commonly downloaded from the internet must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverrideAppRepUnknown" ` + | Select-Object -ExpandProperty "PreventOverrideAppRepUnknown" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1070-IE11" + Task = "Prevent per-user installation of ActiveX controls must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security\ActiveX" ` + -Name "BlockNonAdminActiveXInstall" ` + | Select-Object -ExpandProperty "BlockNonAdminActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1075-IE11" + Task = "Prevent ignoring certificate errors option must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "PreventIgnoreCertErrors" ` + | Select-Object -ExpandProperty "PreventIgnoreCertErrors" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1080-IE11" + Task = "Turn on SmartScreen Filter scan option for the Internet Zone must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1085-IE11" + Task = "Turn on SmartScreen Filter scan option for the Restricted Sites Zone must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1090-IE11" + Task = "The Initialize and script ActiveX controls not marked as safe must be disallowed (Intranet Zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1095-IE11" + Task = "The Initialize and script ActiveX controls not marked as safe must be disallowed (Trusted Sites Zone)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1100-IE11" + Task = "Allow Fallback to SSL 3.0 (Internet Explorer) must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "EnableSSL3Fallback" ` + | Select-Object -ExpandProperty "EnableSSL3Fallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1105-IE11" + Task = "Run once selection for running outdated ActiveX controls must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "RunThisTimeEnabled" ` + | Select-Object -ExpandProperty "RunThisTimeEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1110-IE11" + Task = "Enabling outdated ActiveX controls for Internet Explorer must be blocked." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "VersionCheckEnabled" ` + | Select-Object -ExpandProperty "VersionCheckEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1115-IE11" + Task = "Use of the Tabular Data Control (TDC) ActiveX control must be disabled for the Internet Zone." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120c" ` + | Select-Object -ExpandProperty "120c" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1120-IE11" + Task = "Use of the Tabular Data Control (TDC) ActiveX control must be disabled for the Restricted Sites Zone." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120c" ` + | Select-Object -ExpandProperty "120c" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1125-IE11" + Task = "VBScript must not be allowed to run in Internet Explorer (Internet zone).(This policy setting will only exist on Windows 10 Redstone 2 or later)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "140C" ` + | Select-Object -ExpandProperty "140C" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "DTBI1130-IE11" + Task = "VBScript must not be allowed to run in Internet Explorer (Restricted Sites zone).(This policy setting will only exist on Windows 10 Redstone 2 or later)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "140C" ` + | Select-Object -ExpandProperty "140C" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Internet Explorer 11-MS-2004#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Internet Explorer 11-MS-2004#RegistrySettings.ps1 new file mode 100644 index 0000000..e25ac0f --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Internet Explorer 11-MS-2004#RegistrySettings.ps1 @@ -0,0 +1,4860 @@ +[AuditTest] @{ + Id = "REG-001" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "FormSuggest Passwords" ` + | Select-Object -ExpandProperty "FormSuggest Passwords" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-002" + Task = "Ensure 'Turn on the auto-complete feature for user names and passwords on forms' is set to 'no'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "FormSuggest PW Ask" ` + | Select-Object -ExpandProperty "FormSuggest PW Ask" + + if ($regValue -ne "no") { + return @{ + Message = "Registry value is '$regValue'. Expected: no" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-003" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "FormSuggest Passwords" ` + | Select-Object -ExpandProperty "FormSuggest Passwords" + + if ($regValue -ne "no") { + return @{ + Message = "Registry value is '$regValue'. Expected: no" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-001" + Task = "Ensure 'Remove `"Run this time`" button for outdated ActiveX controls in Internet Explorer ' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "RunThisTimeEnabled" ` + | Select-Object -ExpandProperty "RunThisTimeEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-002" + Task = "Ensure 'Turn off blocking of outdated ActiveX controls for Internet Explorer' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "VersionCheckEnabled" ` + | Select-Object -ExpandProperty "VersionCheckEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-003" + Task = "Ensure 'Allow software to run or install even if the signature is invalid' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "RunInvalidSignatures" ` + | Select-Object -ExpandProperty "RunInvalidSignatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-004" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "CheckExeSignatures" ` + | Select-Object -ExpandProperty "CheckExeSignatures" + + if ($regValue -ne "yes") { + return @{ + Message = "Registry value is '$regValue'. Expected: yes" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-005" + Task = "Ensure 'Turn on 64-bit tab processes when running in Enhanced Protected Mode on 64-bit versions of Windows' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation64Bit" ` + | Select-Object -ExpandProperty "Isolation64Bit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-006" + Task = "Ensure 'Do not allow ActiveX controls to run in Protected Mode when Enhanced Protected Mode is enabled' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "DisableEPMCompat" ` + | Select-Object -ExpandProperty "DisableEPMCompat" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-007" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation" ` + | Select-Object -ExpandProperty "Isolation" + + if ($regValue -ne "PMEM") { + return @{ + Message = "Registry value is '$regValue'. Expected: PMEM" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-008" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-009" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-010" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-011" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-012" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-013" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-014" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-015" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-016" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-017" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-018" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-019" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-020" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-021" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-022" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-023" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-024" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-025" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-026" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-027" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-028" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-029" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-030" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-031" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-032" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverrideAppRepUnknown" ` + | Select-Object -ExpandProperty "PreventOverrideAppRepUnknown" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-033" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-034" + Task = "Ensure 'Prevent managing SmartScreen Filter' is set to 'On'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-035" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Restrictions" ` + -Name "NoCrashDetection" ` + | Select-Object -ExpandProperty "NoCrashDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-036" + Task = "Ensure 'Turn off the Security Settings Check feature' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security" ` + -Name "DisableSecuritySettingsCheck" ` + | Select-Object -ExpandProperty "DisableSecuritySettingsCheck" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-037" + Task = "Ensure 'Prevent per-user installation of ActiveX controls' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security\ActiveX" ` + -Name "BlockNonAdminActiveXInstall" ` + | Select-Object -ExpandProperty "BlockNonAdminActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-038" + Task = "Ensure 'Specify use of ActiveX Installer Service for installation of ActiveX controls' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AxInstaller" ` + -Name "OnlyUseAXISForActiveXInstall" ` + | Select-Object -ExpandProperty "OnlyUseAXISForActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-039" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_zones_map_edit" ` + | Select-Object -ExpandProperty "Security_zones_map_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-040" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_options_edit" ` + | Select-Object -ExpandProperty "Security_options_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-041" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_HKLM_only" ` + | Select-Object -ExpandProperty "Security_HKLM_only" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-042" + Task = "Ensure 'Check for server certificate revocation' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "CertificateRevocation" ` + | Select-Object -ExpandProperty "CertificateRevocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-043" + Task = "Ensure 'Prevent ignoring certificate errors' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "PreventIgnoreCertErrors" ` + | Select-Object -ExpandProperty "PreventIgnoreCertErrors" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-044" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "WarnOnBadCertRecving" ` + | Select-Object -ExpandProperty "WarnOnBadCertRecving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-045" + Task = "Ensure 'Allow fallback to SSL 3.0 (Internet Explorer)' is set to 'No Sites'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "EnableSSL3Fallback" ` + | Select-Object -ExpandProperty "EnableSSL3Fallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-046" + Task = "Ensure 'Turn off encryption support' is set to 'Use TLS 1.1 and TLS 1.2'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "SecureProtocols" ` + | Select-Object -ExpandProperty "SecureProtocols" + + if ($regValue -ne 2560) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2560" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-047" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-048" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-049" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-050" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Lockdown_Zones\3]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\3" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-051" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Lockdown_Zones\4]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-052" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-053" + Task = "Ensure 'Intranet Sites: Include all network paths (UNCs)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap" ` + -Name "UNCAsIntranet" ` + | Select-Object -ExpandProperty "UNCAsIntranet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-054" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-055" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-056" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-057" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-058" + Task = "Ensure 'Java permissions' is set to 'High safety'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-059" + Task = "Ensure 'Java permissions' is set to 'High safety'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-060" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-061" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-062" + Task = "Ensure 'Run .NET Framework-reliant components signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-063" + Task = "Ensure 'Allow script-initiated windows without size or position constraints' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-064" + Task = "Ensure 'Allow drag and drop or copy and paste files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-065" + Task = "Ensure 'Include local path when user is uploading files to a server' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-066" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-067" + Task = "Ensure 'Access data sources across domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-068" + Task = "Ensure 'Launching applications and files in an IFRAME' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-069" + Task = "Ensure 'Automatic prompting for file downloads' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-070" + Task = "Ensure 'Allow scriptlets' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-071" + Task = "Ensure 'Allow scripting of Internet Explorer WebBrowser controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-072" + Task = "Ensure 'Use Pop-up Blocker' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-073" + Task = "Ensure 'Turn on Protected Mode' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-074" + Task = "Ensure 'Allow updates to status bar via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-075" + Task = "Ensure 'Userdata persistence' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-076" + Task = "Ensure 'Allow loading of XAML files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-077" + Task = "Ensure 'Run .NET Framework-reliant components not signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-078" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-079" + Task = "Ensure 'Download signed ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-080" + Task = "Ensure 'Logon options' is set to 'Prompt for user name and password'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-081" + Task = "Ensure 'Enable dragging of content from different domains within a window' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-082" + Task = "Ensure 'Download unsigned ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-083" + Task = "Ensure 'Allow only approved domains to use ActiveX controls without prompt' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-084" + Task = "Ensure 'Allow cut, copy or paste operations from the clipboard via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-085" + Task = "Ensure 'Turn on Cross-Site Scripting Filter' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-086" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-087" + Task = "Ensure 'Navigate windows and frames across different domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-088" + Task = "Ensure 'Enable dragging of content from different domains across windows' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-089" + Task = "Ensure 'Web sites in less privileged Web content zones can navigate into this zone' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-090" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Zones\3]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-091" + Task = "Ensure 'Show security warning for potentially unsafe files' is set to 'Prompt'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-092" + Task = "Ensure 'Allow only approved domains to use the TDC ActiveX control' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120c" ` + | Select-Object -ExpandProperty "120c" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-093" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "140C" ` + | Select-Object -ExpandProperty "140C" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-094" + Task = "Ensure 'Allow META REFRESH' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1608" ` + | Select-Object -ExpandProperty "1608" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-095" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-096" + Task = "Ensure 'Download signed ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-097" + Task = "Ensure 'Navigate windows and frames across different domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-098" + Task = "Ensure 'Allow only approved domains to use ActiveX controls without prompt' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-099" + Task = "Ensure 'Use Pop-up Blocker' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-100" + Task = "Ensure 'Download unsigned ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-101" + Task = "Ensure 'Userdata persistence' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-102" + Task = "Ensure 'Allow cut, copy or paste operations from the clipboard via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-103" + Task = "Ensure 'Include local path when user is uploading files to a server' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-104" + Task = "Ensure 'Access data sources across domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-105" + Task = "Ensure 'Allow script-initiated windows without size or position constraints' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-106" + Task = "Ensure 'Run .NET Framework-reliant components not signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-107" + Task = "Ensure 'Automatic prompting for file downloads' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-108" + Task = "Ensure 'Allow binary and script behaviors' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2000" ` + | Select-Object -ExpandProperty "2000" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-109" + Task = "Ensure 'Scripting of Java applets' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1402" ` + | Select-Object -ExpandProperty "1402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-110" + Task = "Ensure 'Allow file downloads' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1803" ` + | Select-Object -ExpandProperty "1803" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-111" + Task = "Ensure 'Allow loading of XAML files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-112" + Task = "Ensure 'Allow active scripting' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1400" ` + | Select-Object -ExpandProperty "1400" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-113" + Task = "Ensure 'Logon options' is set to 'Anonymous logon'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-114" + Task = "Ensure 'Run .NET Framework-reliant components signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-115" + Task = "Ensure 'Turn on Protected Mode' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-116" + Task = "Ensure 'Turn on Cross-Site Scripting Filter' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-117" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-118" + Task = "Ensure 'Allow scriptlets' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-119" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-120" + Task = "Ensure 'Allow scripting of Internet Explorer WebBrowser controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-121" + Task = "Ensure 'Enable dragging of content from different domains within a window' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-122" + Task = "Ensure 'Allow drag and drop or copy and paste files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-123" + Task = "Ensure 'Allow updates to status bar via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-124" + Task = "Ensure 'Enable dragging of content from different domains across windows' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-125" + Task = "Ensure 'Script ActiveX controls marked safe for scripting' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1405" ` + | Select-Object -ExpandProperty "1405" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-126" + Task = "Ensure 'Web sites in less privileged Web content zones can navigate into this zone' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-127" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Zones\4]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-128" + Task = "Ensure 'Run ActiveX controls and plugins' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1200" ` + | Select-Object -ExpandProperty "1200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-129" + Task = "Ensure 'Launching applications and files in an IFRAME' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-130" + Task = "Ensure 'Show security warning for potentially unsafe files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-131" + Task = "Ensure 'Allow only approved domains to use the TDC ActiveX control' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120c" ` + | Select-Object -ExpandProperty "120c" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "REG-132" + Task = "Task unavailable" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "140C" ` + | Select-Object -ExpandProperty "140C" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Office Enterprise-CIS-1.2.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Office Enterprise-CIS-1.2.0#RegistrySettings.ps1 new file mode 100644 index 0000000..bf458e1 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Office Enterprise-CIS-1.2.0#RegistrySettings.ps1 @@ -0,0 +1,11884 @@ +# Office root folder +$officePaths = @( + # Office 365 / 2019 / 2021 (the standard install paths) + "C:\Program Files\Microsoft Office\root\Office16", + "C:\Program Files (x86)\Microsoft Office\root\Office16" + + # Office 2016 (MSI) + "C:\Program Files\Microsoft Office\Office16", + "C:\Program Files (x86)\Microsoft Office\Office16", + + # Office 2016 (x32 MSI on x64 OS) + "C:\Program Files (x86)\Microsoft Office\root\Office16", + "C:\Program Files (x86)\Microsoft Office\Office16\", + + # Office 2016 (x64 MSI on x64 OS) + "C:\Program Files\Microsoft Office\Office16\" +) + +# Mapping of applications to exe names +$exeMap = @{ + "Groove" = "GROOVE.EXE" + "Excel" = "EXCEL.EXE" + "Publisher" = "MSPUB.EXE" + "PowerPoint" = "POWERPNT.EXE" + "PowerPoint Viewer" = "PPTVIEW.EXE" + "Project" = "WINPROJ.EXE" + "Word" = "WINWORD.EXE" + "Outlook" = "OUTLOOK.EXE" + "SharePoint Designer" = "SPDESIGN.EXE" + "Expression Web" = "EXPRWD.EXE" + "Access" = "MSACCESS.EXE" + "OneNote" = "ONENOTE.EXE" + "MS Script Editor" = "MSE7.EXE" + "Visio" = "VISIO.EXE" + +} + +# Check if any Office installation path exists -> if not existend, then Office is not installed +$OfficeInstalled = $false +foreach ($path in $officePaths) { + if (Test-Path $path) { + $OfficeInstalled = $true + break + } +} + +# Determine which Office apps are installed +$installedOfficeApps = @{} + +if ($OfficeInstalled) { + foreach ($app in $exeMap.Keys) { + foreach ($path in $officePaths) { + $exePath = Join-Path $path $exeMap[$app] + if (Test-Path $exePath) { + $installedOfficeApps[$app] = $true + break + } + } + if (-not $installedOfficeApps.ContainsKey($app)) { + $installedOfficeApps[$app] = $false + } + } +} +else { + Write-Warning "Office could not be found on this system." + Write-Warning "If Office is installed, please leave a comment in Issue-718 (https://github.com/fbprogmbh/Hardening-Audit-Tool-AuditTAP/issues/718) and provide requested information from 'What happened?' section." +} + +[AuditTest] @{ + Id = "1.1.4.1.1 A" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} + +[AuditTest] @{ + Id = "1.1.4.1.1 B" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.1 C" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.1 D" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.1 E" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.1 F" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.1 G" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.1 H" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.1 I" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.1 J" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.1 K" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.1 L" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.1 M" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.1 N" + Task = "(L1) Ensure 'Add-on Management' is set to Enabled (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ADDON_MANAGEMENT" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 A" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 B" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 C" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 D" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 E" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 F" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 G" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 H" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 I" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 J" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 K" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 L" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 M" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.2 N" + Task = "(L1) Ensure 'Bind to object' is set to 'Enabled' (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SAFE_BINDTOOBJECT" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 A" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled'" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 B" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 C" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 D" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 E" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 F" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 G" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 H" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 I" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 J" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 K" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 L" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 M" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.3 N" + Task = "(L1) Ensure 'Consistent Mime Handling' is set to 'Enabled' (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 A" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 B" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 C" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 D" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 E" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 F" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 G" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 H" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 I" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 J" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 K" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 L" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 M" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.4 N" + Task = "(L1) Ensure 'Disable user name and password' is set to 'Enabled' (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 A" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 B" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 C" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 D" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 E" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 F" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 G" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 H" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 I" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 J" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 K" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 L" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 M" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.5 N" + Task = "(L1) Ensure 'Information Bar' is set to 'Enabled' (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 A" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneDrive for Business"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 B" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 C" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 D" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 E" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 F" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 G" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 H" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 I" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 J" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} + +[AuditTest] @{ + Id = "1.1.4.1.6 K" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 L" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 M" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.6 N" + Task = "(L1) Ensure 'Local Machine Zone Lockdown Security' is set to Enabled (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 A" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 B" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 C" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 D" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 E" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 F" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 G" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 H" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 I" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 J" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 K" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 L" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 M" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.7 N" + Task = "(L1) Ensure 'Mime Sniffing Safety Feature' is set to Enabled (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 A" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 B" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 C" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 D" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 E" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 F" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 G" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 H" + Task = "(L1) Ensure 'Navigate URL' is set to 'Enabled' (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\software\microsoft\internet explorer\main\featurecontrol\feature_validate_navigate_url" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 I" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 J" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 K" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 L" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 M" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.8 N" + Task = "(L1) Ensure 'Navigate URL' is set to Enabled (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_VALIDATE_NAVIGATE_URL" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 A" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 B" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 C" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 D" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 E" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 F" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 G" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 H" + Task = "(L1) Ensure 'Object Caching Protection' is set to 'Enabled' (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\software\microsoft\internet explorer\main\featurecontrol\feature_object_caching" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 I" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 J" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 K" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 L" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 M" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.9 N" + Task = "(L1) Ensure 'Object Caching Protection' is set to Enabled (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 A" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 B" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 C" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 D" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 E" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 F" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 G" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 H" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to 'Enabled' (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\software\microsoft\internet explorer\main\featurecontrol\feature_zone_elevation" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 I" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 J" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 K" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 L" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 M" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.10 N" + Task = "(L1) Ensure 'Protection From Zone Elevation' is set to Enabled (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 A" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 B" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 C" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 D" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 E" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 F" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 G" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 H" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to 'Enabled' (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\software\microsoft\internet explorer\main\featurecontrol\feature_restrict_activexinstall" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 I" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 J" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 K" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 L" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 M" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.11 N" + Task = "(L1) Ensure 'Restrict ActiveX Install' is set to Enabled (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 A" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 B" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 C" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 D" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 E" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 F" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 G" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 H" + Task = "(L1) Ensure 'Restrict File Download' is set to 'Enabled' (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\software\microsoft\internet explorer\main\featurecontrol\feature_restrict_filedownload" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 I" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 J" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 K" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 L" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 M" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.12 N" + Task = "(L1) Ensure 'Restrict File Download' is set to Enabled (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 A" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 B" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 C" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 D" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 E" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 F" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 G" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 H" + Task = "(L1) Ensure 'Saved from URL' is set to 'Enabled' (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\software\microsoft\internet explorer\main\featurecontrol\feature_unc_savedfilecheck" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 I" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 J" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 K" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 L" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 M" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.13 N" + Task = "(L1) Ensure 'Saved from URL' is set to Enabled (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_UNC_SAVEDFILECHECK" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 A" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (groove.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Groove"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "groove.exe" ` + | Select-Object -ExpandProperty "groove.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 B" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 C" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 D" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 E" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (pptview.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint Viewer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "pptview.exe" ` + | Select-Object -ExpandProperty "pptview.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 F" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 G" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 H" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to 'Enabled' (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\software\microsoft\internet explorer\main\featurecontrol\feature_window_restrictions" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 I" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 J" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (spDesign.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["SharePoint Designer"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "spDesign.exe" ` + | Select-Object -ExpandProperty "spDesign.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 K" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (exprwd.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Expression Web"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "exprwd.exe" ` + | Select-Object -ExpandProperty "exprwd.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 L" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 M" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (onent.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "onent.exe" ` + | Select-Object -ExpandProperty "onent.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.4.1.14 N" + Task = "(L1) Ensure 'Scripted Window Security Restrictions' is set to Enabled (mse7.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["MS Script Editor"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "mse7.exe" ` + | Select-Object -ExpandProperty "mse7.exe" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.5.1" + Task = "(L1) Ensure 'Enable Automatic Updates' is set to Enabled" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\software\policies\microsoft\office\16.0\common\officeupdate" ` + -Name "enableautomaticupdates" ` + | Select-Object -ExpandProperty "enableautomaticupdates" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.1.5.2" + Task = "(L1) Ensure 'Hide Option to Enable or Disable Updates' is set to Enabled" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\software\policies\microsoft\office\16.0\common\officeupdate" ` + -Name "hideenabledisableupdates" ` + | Select-Object -ExpandProperty "hideenabledisableupdates" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.1 A" + Task = "(L1) Ensure 'Block Flash activation in Office documents' is set to 'Enabled: Block all activation'" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\office\Common\COM Compatibility" ` + -Name "Comment" ` + | Select-Object -ExpandProperty "Comment" + + if ($regValue -ne "Block all Flash activation") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block all Flash activation" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.1 B" + Task = "(L1) Ensure 'Block Flash activation in Office documents' is set to 'Enabled: Block all activation' (ActivationFilterOverride)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Common\COM Compatibility\{D27CDB6E-AE6D-11CF-96B8-444553540000}" ` + -Name "ActivationFilterOverride" ` + | Select-Object -ExpandProperty "ActivationFilterOverride" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.1 C" + Task = "(L1) Ensure 'Block Flash activation in Office documents' is set to 'Enabled: Block all activation' (Compatibility Flags)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Common\COM Compatibility\{D27CDB6E-AE6D-11CF-96B8-444553540000}" ` + -Name "Compatibility Flags" ` + | Select-Object -ExpandProperty "Compatibility Flags" + + if (($regValue -ne 1024)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1024" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.1 D" + Task = "(L1) Ensure 'Block Flash activation in Office documents' is set to 'Enabled: Block all activation' (ActivationFilterOverride)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Common\COM Compatibility\{D27CDB70-AE6D-11CF-96B8-444553540000}" ` + -Name "ActivationFilterOverride" ` + | Select-Object -ExpandProperty "ActivationFilterOverride" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.1 E" + Task = "(L1) Ensure 'Block Flash activation in Office documents' is set to 'Enabled: Block all activation' (Compatibility Flags)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Common\COM Compatibility\{D27CDB70-AE6D-11CF-96B8-444553540000}" ` + -Name "Compatibility Flags" ` + | Select-Object -ExpandProperty "Compatibility Flags" + + if (($regValue -ne 1024)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1024" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.1 F" + Task = "(L1) Ensure 'Block Flash activation in Office documents' is set to 'Enabled: Block all activation' (ActivationFilterOverride, WOW6432)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Office\Common\COM Compatibility\{D27CDB6E-AE6D-11CF-96B8-444553540000}" ` + -Name "ActivationFilterOverride" ` + | Select-Object -ExpandProperty "ActivationFilterOverride" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.1 G" + Task = "(L1) Ensure 'Block Flash activation in Office documents' is set to 'Enabled: Block all activation' (Compatibility Flags, WOW6432)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Office\Common\COM Compatibility\{D27CDB6E-AE6D-11CF-96B8-444553540000}" ` + -Name "Compatibility Flags" ` + | Select-Object -ExpandProperty "Compatibility Flags" + + if (($regValue -ne 1024)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1024" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.1 H" + Task = "(L1) Ensure 'Block Flash activation in Office documents' is set to 'Enabled: Block all activation' (ActivationFilterOverride, WOW6432)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Office\Common\COM Compatibility\{D27CDB70-AE6D-11CF-96B8-444553540000}" ` + -Name "ActivationFilterOverride" ` + | Select-Object -ExpandProperty "ActivationFilterOverride" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.1 I" + Task = "(L1) Ensure 'Block Flash activation in Office documents' is set to 'Enabled: Block all activation' (Compatibility Flags, WOW6432)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Office\Common\COM Compatibility\{D27CDB70-AE6D-11CF-96B8-444553540000}" ` + -Name "Compatibility Flags" ` + | Select-Object -ExpandProperty "Compatibility Flags" + + if (($regValue -ne 1024)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1024" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.2 A" + Task = "(L1) Ensure 'Restrict legacy JScript execution for Office' is set to 'Enabled' (excel.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Excel"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\internet explorer\main\featurecontrol\FEATURE_RESTRICT_LEGACY_JSCRIPT_PER_SECURITY_ZONE" ` + -Name "excel.exe" ` + | Select-Object -ExpandProperty "excel.exe" + + if (($regValue -ne 69632)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 69632" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.2 B" + Task = "(L1) Ensure 'Restrict legacy JScript execution for Office' is set to 'Enabled' (msaccess.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Access"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\internet explorer\main\featurecontrol\FEATURE_RESTRICT_LEGACY_JSCRIPT_PER_SECURITY_ZONE" ` + -Name "msaccess.exe" ` + | Select-Object -ExpandProperty "msaccess.exe" + + if (($regValue -ne 69632)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 69632" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.2 C" + Task = "(L1) Ensure 'Restrict legacy JScript execution for Office' is set to 'Enabled' (mspub.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Publisher"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\internet explorer\main\featurecontrol\FEATURE_RESTRICT_LEGACY_JSCRIPT_PER_SECURITY_ZONE" ` + -Name "mspub.exe" ` + | Select-Object -ExpandProperty "mspub.exe" + + if (($regValue -ne 69632)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 69632" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.2 D" + Task = "(L1) Ensure 'Restrict legacy JScript execution for Office' is set to 'Enabled' (onenote.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["OneNote"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\internet explorer\main\featurecontrol\FEATURE_RESTRICT_LEGACY_JSCRIPT_PER_SECURITY_ZONE" ` + -Name "onenote.exe" ` + | Select-Object -ExpandProperty "onenote.exe" + + if (($regValue -ne 69632)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 69632" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.2 E" + Task = "(L1) Ensure 'Restrict legacy JScript execution for Office' is set to 'Enabled' (outlook.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Outlook"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\internet explorer\main\featurecontrol\FEATURE_RESTRICT_LEGACY_JSCRIPT_PER_SECURITY_ZONE" ` + -Name "outlook.exe" ` + | Select-Object -ExpandProperty "outlook.exe" + + if (($regValue -ne 69632)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 69632" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.2 F" + Task = "(L1) Ensure 'Restrict legacy JScript execution for Office' is set to 'Enabled' (powerpnt.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["PowerPoint"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\internet explorer\main\featurecontrol\FEATURE_RESTRICT_LEGACY_JSCRIPT_PER_SECURITY_ZONE" ` + -Name "powerpnt.exe" ` + | Select-Object -ExpandProperty "powerpnt.exe" + + if (($regValue -ne 69632)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 69632" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.2 G" + Task = "(L1) Ensure 'Restrict legacy JScript execution for Office' is set to 'Enabled' (visio.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Visio"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\internet explorer\main\featurecontrol\FEATURE_RESTRICT_LEGACY_JSCRIPT_PER_SECURITY_ZONE" ` + -Name "visio.exe" ` + | Select-Object -ExpandProperty "visio.exe" + + if (($regValue -ne 69632)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 69632" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.2 H" + Task = "(L1) Ensure 'Restrict legacy JScript execution for Office' is set to 'Enabled' (winproj.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Project"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\internet explorer\main\featurecontrol\FEATURE_RESTRICT_LEGACY_JSCRIPT_PER_SECURITY_ZONE" ` + -Name "winproj.exe" ` + | Select-Object -ExpandProperty "winproj.exe" + + if (($regValue -ne 69632)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 69632" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "1.3.2 I" + Task = "(L1) Ensure 'Restrict legacy JScript execution for Office' is set to 'Enabled' (winword.exe)" + Test = { + # new logic: + # - if no Office installed at all -> skip test + # - if Office installed but app not installed -> skip test + # - else run test as normal + + if (-not $OfficeInstalled) { + return @{ + Message = "No Office installation detected, skipping test." + Status = "None" + } + } + elseif (-not $installedOfficeApps["Word"]) { + return @{ + Message = "Application not installed, skipping test." + Status = "None" + } + } + else { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\internet explorer\main\featurecontrol\FEATURE_RESTRICT_LEGACY_JSCRIPT_PER_SECURITY_ZONE" ` + -Name "winword.exe" ` + | Select-Object -ExpandProperty "winword.exe" + + if (($regValue -ne 69632)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 69632" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 GDPR-MS-16082019#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 GDPR-MS-16082019#RegistrySettings.ps1 new file mode 100644 index 0000000..606764a --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 GDPR-MS-16082019#RegistrySettings.ps1 @@ -0,0 +1,4215 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$avstatus = CheckForActiveAV +$windefrunning = CheckWindefRunning +[AuditTest] @{ + Id = "1" + Task = "Turn off Automatic Root Certificates Update" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SystemCertificates\AuthRoot" ` + -Name "DisableRootAutoUpdate" ` + | Select-Object -ExpandProperty "DisableRootAutoUpdate" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.1.1" + Task = "Disable Allow Cortana" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCortana" ` + | Select-Object -ExpandProperty "AllowCortana" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.1.2" + Task = "Disable Allow search and Cortana to use location" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowSearchToUseLocation" ` + | Select-Object -ExpandProperty "AllowSearchToUseLocation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.1.3" + Task = "Do not allow web search" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "DisableWebSearch" ` + | Select-Object -ExpandProperty "DisableWebSearch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.1.4" + Task = "Don't search the web or display web results in Search" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "ConnectedSearchUseWeb" ` + | Select-Object -ExpandProperty "ConnectedSearchUseWeb" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.1.5" + Task = "Set Set what information is shared in Search to Anonymous info" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "ConnectedSearchPrivacy" ` + | Select-Object -ExpandProperty "ConnectedSearchPrivacy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.1" + Task = "Prevent Windows from setting the time automatically" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Parameters" ` + -Name "Type" ` + | Select-Object -ExpandProperty "Type" + + if ($regValue -ne "NoSync") { + return @{ + Message = "Registry value is '$regValue'. Expected: NoSync" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.2" + Task = "Disable Windows NTP Client" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32time\TimeProviders\NtpClient" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4" + Task = "Prevent Windows from retrieving device metadata from the Internet" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" ` + -Name "PreventDeviceMetadataFromNetwork" ` + | Select-Object -ExpandProperty "PreventDeviceMetadataFromNetwork" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5" + Task = "Turn off Find My Device" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FindMyDevice" ` + -Name "AllowFindMyDevice" ` + | Select-Object -ExpandProperty "AllowFindMyDevice" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "6" + Task = "Disable Font Providers" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableFontProviders" ` + | Select-Object -ExpandProperty "EnableFontProviders" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "7" + Task = "Turn off Insider Preview builds for Windows 10" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" ` + -Name "AllowBuildPreview" ` + | Select-Object -ExpandProperty "AllowBuildPreview" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.1" + Task = "Disable Suggested Sites" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Suggested Sites" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.2" + Task = "Disable Allow Microsoft services to provide enhanced suggestions as the user types in the Address Bar" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer" ` + -Name "AllowServicePoweredQSA" ` + | Select-Object -ExpandProperty "AllowServicePoweredQSA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.3" + Task = "Turn off the auto-complete feature for web addresses" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Explorer\AutoComplete" ` + -Name "AutoSuggest" ` + | Select-Object -ExpandProperty "AutoSuggest" + + if ($regValue -ne "No") { + return @{ + Message = "Registry value is '$regValue'. Expected: No" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.4" + Task = "Turn off browser geolocation" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Geolocation" ` + -Name "PolicyDisableGeolocation" ` + | Select-Object -ExpandProperty "PolicyDisableGeolocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.5" + Task = "Prevent managing SmartScreen filter" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.6" + Task = "Turn off Compatibility View." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\BrowserEmulation" ` + -Name "DisableSiteListEditing" ` + | Select-Object -ExpandProperty "DisableSiteListEditing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.7" + Task = "Turn off the flip ahead with page prediction feature" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\FlipAhead" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.8" + Task = "Turn off background synchronization for feeds and Web Slices" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "BackgroundSyncStatus" ` + | Select-Object -ExpandProperty "BackgroundSyncStatus" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.9" + Task = "Disable Allow Online Tips" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "AllowOnlineTips" ` + | Select-Object -ExpandProperty "AllowOnlineTips" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.10" + Task = "Set home page blank" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Start Page" ` + | Select-Object -ExpandProperty "Start Page" + + if ($regValue -ne "about:blank") { + return @{ + Message = "Registry value is '$regValue'. Expected: about:blank" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.11" + Task = "Disable changing home page settings" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "HomePage" ` + | Select-Object -ExpandProperty "HomePage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.12" + Task = "Prevent running First Run wizard" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Internet Explorer\Main" ` + -Name "DisableFirstRunCustomize and set it to Go directly to home page" ` + | Select-Object -ExpandProperty "DisableFirstRunCustomize and set it to Go directly to home page" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.0.13" + Task = "Specify default behavior for a new tab" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Internet Explorer\TabbedBrowsing" ` + -Name "NewTabPageShow" ` + | Select-Object -ExpandProperty "NewTabPageShow" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8.1" + Task = "Turn off Automatic download of the ActiveX VersionList" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\VersionManager" ` + -Name "DownloadVersionList" ` + | Select-Object -ExpandProperty "DownloadVersionList" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9" + Task = "Turn off License Manager related traffic" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LicenseManager" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "10" + Task = "Turn Off notifications network usage" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "11" + Task = "Turn off mail synchronization for Microsoft Accounts that are configured on the device" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Mail" ` + -Name "ManualLaunchAllowed" ` + | Select-Object -ExpandProperty "ManualLaunchAllowed" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "12" + Task = "Disable the Microsoft Account Sign-In Assistant" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\wlidsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "13.1" + Task = "Disable Allow Address Bar drop-down list suggestions" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\ServiceUI" ` + -Name "ShowOneBox" ` + | Select-Object -ExpandProperty "ShowOneBox" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "13.2" + Task = "Disable Allow configuration updates for the Books Library" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\BooksLibrary" ` + -Name "AllowConfigurationUpdateForBooksLibrary" ` + | Select-Object -ExpandProperty "AllowConfigurationUpdateForBooksLibrary" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "13.3" + Task = "Disable Configure Autofill" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main" ` + -Name "Use FormSuggest" ` + | Select-Object -ExpandProperty "Use FormSuggest" + + if ($regValue -ne "No") { + return @{ + Message = "Registry value is '$regValue'. Expected: No" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "13.4" + Task = "Configure Do Not Track" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main" ` + -Name "DoNotTrack" ` + | Select-Object -ExpandProperty "DoNotTrack" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "13.5" + Task = "Disable Configure Password Manager" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main" ` + -Name "FormSuggest Passwords" ` + | Select-Object -ExpandProperty "FormSuggest Passwords" + + if ($regValue -ne "No") { + return @{ + Message = "Registry value is '$regValue'. Expected: No" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "13.6" + Task = "Disable Configure search suggestions in Address Bar" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes" ` + -Name "ShowSearchSuggestionsGlobal" ` + | Select-Object -ExpandProperty "ShowSearchSuggestionsGlobal" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "13.7" + Task = "Disable Configure Windows Defender SmartScreen Filter (Windows 10, version 1703)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "13.8" + Task = "Disable Allow web content on New Tab page" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\ServiceUI" ` + -Name "AllowWebContentOnNewTabPage" ` + | Select-Object -ExpandProperty "AllowWebContentOnNewTabPage" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "13.9" + Task = "Configure corporate Home pages" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Internet Settings" ` + -Name "ProvisionedHomePages" ` + | Select-Object -ExpandProperty "ProvisionedHomePages" + + if ($regValue -ne "about:blank") { + return @{ + Message = "Registry value is '$regValue'. Expected: about:blank" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "13.10" + Task = "Prevent the First Run webpage from opening on Microsoft Edge" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main" ` + -Name "PreventFirstRunPage" ` + | Select-Object -ExpandProperty "PreventFirstRunPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "13.11" + Task = "Disable Compatibility View." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\BrowserEmulation" ` + -Name "MSCompatibilityMode" ` + | Select-Object -ExpandProperty "MSCompatibilityMode" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "14" + Task = "Turn off Windows Network Connectivity Status Indicator active tests" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkConnectivityStatusIndicator" ` + -Name "NoActiveProbe" ` + | Select-Object -ExpandProperty "NoActiveProbe" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "15.1" + Task = "Turn off Automatic Download and Update of Map Data" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Maps" ` + -Name "AutoDownloadAndUpdateMapData" ` + | Select-Object -ExpandProperty "AutoDownloadAndUpdateMapData" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "15.2" + Task = "Turn off unsolicited network traffic on the Offline Maps settings page" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Maps" ` + -Name "AllowUntriggeredNetworkTrafficOnSettingsPage" ` + | Select-Object -ExpandProperty "AllowUntriggeredNetworkTrafficOnSettingsPage" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "16.1" + Task = "Prevent the usage of OneDrive for file storage" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "16.2" + Task = "Prevent OneDrive from generating network traffic until the user signs in to OneDrive (Enable)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\OneDrive" ` + -Name "PreventNetworkTrafficPreUserSignIn" ` + | Select-Object -ExpandProperty "PreventNetworkTrafficPreUserSignIn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.1" + Task = "Turn off Let apps use advertising ID to make ads more interesting to you based on your app usage (turning this off will reset your ID)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AdvertisingInfo" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.2" + Task = "Turn off Let apps use advertising ID to make ads more interesting to you based on your app usage (turning this off will reset your ID)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" ` + -Name "DisabledByGroupPolicy" ` + | Select-Object -ExpandProperty "DisabledByGroupPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.3" + Task = "Turn off Let websites provide locally relevant content by accessing my language list" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Control Panel\International\User Profile" ` + -Name "HttpAcceptLanguageOptOut" ` + | Select-Object -ExpandProperty "HttpAcceptLanguageOptOut" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.4" + Task = "Turn off Let Windows track app launches to improve Start and search results" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" ` + -Name "Start_TrackProgs" ` + | Select-Object -ExpandProperty "Start_TrackProgs" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.2.1" + Task = "Turn off Location for this device" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessLocation" ` + | Select-Object -ExpandProperty "LetAppsAccessLocation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.2.2" + Task = "Turn off Location" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.1" + Task = "Turn off Let apps use my camera" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessCamera" ` + | Select-Object -ExpandProperty "LetAppsAccessCamera" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.1" + Task = "Turn off Let apps use my microphone" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessMicrophone" ` + | Select-Object -ExpandProperty "LetAppsAccessMicrophone" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.1" + Task = "Turn off notifications network usage" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.2" + Task = "Turn off Let apps access my notifications" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessNotifications" ` + | Select-Object -ExpandProperty "LetAppsAccessNotifications" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.1" + Task = "Turn off dictation of your voice, speaking to Cortana and other apps, and to prevent sending your voice input to Microsoft Speech services" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy" ` + -Name "HasAccepted" ` + | Select-Object -ExpandProperty "HasAccepted" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.2" + Task = "Turn off updates to the speech recognition and speech synthesis models" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Speech" ` + -Name "AllowSpeechModelUpdate" ` + | Select-Object -ExpandProperty "AllowSpeechModelUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.1" + Task = "Turn off Let apps access my name, picture, and other account info" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessAccountInfo" ` + | Select-Object -ExpandProperty "LetAppsAccessAccountInfo" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8" + Task = "Turn off Choose apps that can access contacts" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessContacts" ` + | Select-Object -ExpandProperty "LetAppsAccessContacts" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.1" + Task = "Turn off Let apps access my calendar" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessCalendar" ` + | Select-Object -ExpandProperty "LetAppsAccessCalendar" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10" + Task = "Turn off Let apps access my call history" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessCallHistory" ` + | Select-Object -ExpandProperty "LetAppsAccessCallHistory" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.11" + Task = "Turn off Let apps access and send email" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessEmail" ` + | Select-Object -ExpandProperty "LetAppsAccessEmail" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.12.1" + Task = "Turn off Let apps read or send messages (text or MMS)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessMessaging" ` + | Select-Object -ExpandProperty "LetAppsAccessMessaging" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.12.3" + Task = "Turn off Message Sync" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Messaging" ` + -Name "AllowMessageSync" ` + | Select-Object -ExpandProperty "AllowMessageSync" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.13.1" + Task = "Turn off Let apps make phone calls" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessPhone" ` + | Select-Object -ExpandProperty "LetAppsAccessPhone" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.14.1" + Task = "Turn off Let apps control radios" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessRadios" ` + | Select-Object -ExpandProperty "LetAppsAccessRadios" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.15.1" + Task = "Turn off Let apps automatically share and sync info with wireless devices that do not explicitly pair with your PC, tablet, or phone" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsSyncWithDevices" ` + | Select-Object -ExpandProperty "LetAppsSyncWithDevices" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.15.2" + Task = "Turn off Let your apps use your trusted devices (hardware you've already connected, or comes with your PC, tablet, or phone)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessTrustedDevices" ` + | Select-Object -ExpandProperty "LetAppsAccessTrustedDevices" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.16.1" + Task = "Do not show feedback notificationsk" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection" ` + -Name "DoNotShowFeedbackNotifications" ` + | Select-Object -ExpandProperty "DoNotShowFeedbackNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.16.2" + Task = "Set Send your device data to Microsoft to Basic" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + $allowedNames = @("Windows 10 Home", "Windows 11 Home", "Windows 10 Pro", "Windows 11 Pro") + $productname = Get-ComputerInfo | select -ExpandProperty OsName + if (($allowedNames -contains $productname) -and ($regValue -eq 1)){ + return @{ + Message = "Registry value is '$regValue'. Your OS $productname does not support 'Diagnostic data off'." + Status = "Warning" + } + } + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.16.3" + Task = "Turn off tailored experiences with relevant tips and recommendations by using your diagnostics data" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.16.4" + Task = "Turn off tailored experiences with relevant tips and recommendations by using your diagnostics data" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableTailoredExperiencesWithDiagnosticData" ` + | Select-Object -ExpandProperty "DisableTailoredExperiencesWithDiagnosticData" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.17" + Task = "Turn off Let apps run in the background" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsRunInBackground" ` + | Select-Object -ExpandProperty "LetAppsRunInBackground" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.18" + Task = "Turn off Let Windows and your apps use your motion data and collect motion history" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessMotion" ` + | Select-Object -ExpandProperty "LetAppsAccessMotion" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.19" + Task = "Set Let Windows apps access Tasks to Force Deny" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsAccessTasks" ` + | Select-Object -ExpandProperty "LetAppsAccessTasks" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.20" + Task = "Let Windows apps access diagnostic information about other apps" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsGetDiagnosticInfo" ` + | Select-Object -ExpandProperty "LetAppsGetDiagnosticInfo" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.21" + Task = "Turn off Inking & Typing data collection" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\InputPersonalization" ` + -Name "RestrictImplicitTextCollection" ` + | Select-Object -ExpandProperty "RestrictImplicitTextCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.22.1" + Task = "Disable Activity Feed" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnableActivityFeed" ` + | Select-Object -ExpandProperty "EnableActivityFeed" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.22.2" + Task = "Disable Allow publishing of User Activities" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "PublishUserActivities" ` + | Select-Object -ExpandProperty "PublishUserActivities" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.22.3" + Task = "Disable Allow upload of User Activities" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "UploadUserActivities" ` + | Select-Object -ExpandProperty "UploadUserActivities" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.23.1" + Task = "Disable Let Windows apps activate with voice" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsActivateWithVoice" ` + | Select-Object -ExpandProperty "LetAppsActivateWithVoice" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.23.2" + Task = "Disable Allow publishing of User Activities" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "PublishUserActivities" ` + | Select-Object -ExpandProperty "PublishUserActivities" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19" + Task = "Turn off KMS Client Online AVS Validation" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" ` + -Name "NoGenTicket" ` + | Select-Object -ExpandProperty "NoGenTicket" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "20" + Task = "Disable Allow downloading updates to the Disk Failure Prediction Model" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\StorageHealth" ` + -Name "AllowDiskHealthModelUpdates" ` + | Select-Object -ExpandProperty "AllowDiskHealthModelUpdates" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "21.1" + Task = "Enable Do not sync" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\SettingSync" ` + -Name "DisableSettingSync" ` + | Select-Object -ExpandProperty "DisableSettingSync" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "21.2" + Task = "Disable Allow users to turn syncing on" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\SettingSync" ` + -Name "DisableSettingSyncUserOverride" ` + | Select-Object -ExpandProperty "DisableSettingSyncUserOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "21.3" + Task = "Turn off Messaging cloud sync" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Messaging" ` + -Name "CloudServiceSyncEnabled" ` + | Select-Object -ExpandProperty "CloudServiceSyncEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "22" + Task = "Set Teredo State to disabled state" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TCPIP\v6Transition" ` + -Name "Teredo_State" ` + | Select-Object -ExpandProperty "Teredo_State" + + if ($regValue -ne "Disabled") { + return @{ + Message = "Registry value is '$regValue'. Expected: Disabled" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "23" + Task = "Turn off Connect to suggested open hotspots and Connect to networks shared by my contacts" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config" ` + -Name "AutoConnectAllowedOEM" ` + | Select-Object -ExpandProperty "AutoConnectAllowedOEM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24.0.1" + Task = "Disable Join Microsoft MAPS" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpyNetReporting" ` + | Select-Object -ExpandProperty "SpyNetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24.0.3" + Task = "Set Send file samples when further analysis is required to Never Send" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SubmitSamplesConsent" ` + | Select-Object -ExpandProperty "SubmitSamplesConsent" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24.0.4" + Task = "Set Define the order of sources for downloading definition updates to FileShares" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Signature Updates" ` + -Name "FallbackOrder" ` + | Select-Object -ExpandProperty "FallbackOrder" + + if ($regValue -ne "FileShares") { + return @{ + Message = "Registry value is '$regValue'. Expected: FileShares" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24.0.5" + Task = "Define Define file shares for downloading definition updates to Nothing" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Signature Updates" ` + -Name "DefinitionUpdateFileSharesSources" ` + | Select-Object -ExpandProperty "DefinitionUpdateFileSharesSources" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24.0.6" + Task = "Turn off Malicious Software Reporting Tool diagnostic data" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\MRT" ` + -Name "DontReportInfectionInformation" ` + | Select-Object -ExpandProperty "DontReportInfectionInformation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24.0.7" + Task = "Turn off Enhanced Notifications as follows" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Reporting" ` + -Name "DisableEnhancedNotifications" ` + | Select-Object -ExpandProperty "DisableEnhancedNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24.1.1" + Task = "Disable Windows Defender Smartscreen" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24.1.2" + Task = "Disable Windows Defender Smartscreen" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\SmartScreen" ` + -Name "ConfigureAppInstallControlEnabled" ` + | Select-Object -ExpandProperty "ConfigureAppInstallControlEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24.1.3" + Task = "Disable Windows Defender Smartscreen" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\SmartScreen" ` + -Name "ConfigureAppInstallControl" ` + | Select-Object -ExpandProperty "ConfigureAppInstallControl" + + if ($regValue -ne "Anywhere") { + return @{ + Message = "Registry value is '$regValue'. Expected: Anywhere" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "25.1" + Task = "Turn off all Windows spotlight features" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsSpotlightFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsSpotlightFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "25.2" + Task = "Do not display the Lock Screen" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreen" ` + | Select-Object -ExpandProperty "NoLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "25.3" + Task = "Force a specific default lock screen image and logon image" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "LockScreenImage" ` + | Select-Object -ExpandProperty "LockScreenImage" + + if ($regValue -ne "C:\windows\web\screen\lockscreen.jpg") { + return @{ + Message = "Registry value is '$regValue'. Expected: C:\windows\web\screen\lockscreen.jpg" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "25.4" + Task = "Turn off fun facts, tips, tricks, and more on lock screen" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "LockScreenOverlaysDisabled" ` + | Select-Object -ExpandProperty "LockScreenOverlaysDisabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "25.5" + Task = "Do not show Windows tips" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableSoftLanding" ` + | Select-Object -ExpandProperty "DisableSoftLanding" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "25.6" + Task = "Turn off Microsoft consumer experiences" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "26.1" + Task = "Turn off the ability to launch apps from the Microsoft Store that were preinstalled or downloaded" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "DisableStoreApps" ` + | Select-Object -ExpandProperty "DisableStoreApps" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "26.2" + Task = "Turn off the ability to launch apps from the Microsoft Store that were preinstalled or downloaded" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "AutoDownload" ` + | Select-Object -ExpandProperty "AutoDownload" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "27" + Task = "Turn off apps for websites, preventing customers who visit websites that are registered with their associated app from directly launching the app" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableAppUriHandlers" ` + | Select-Object -ExpandProperty "EnableAppUriHandlers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "28.3" + Task = "Enable the Download Mode and set the Download Mode to `"Bypass`" to prevent traffic" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization" ` + -Name "DODownloadMode" ` + | Select-Object -ExpandProperty "DODownloadMode" + + if ($regValue -ne 100) { + return @{ + Message = "Registry value is '$regValue'. Expected: 100" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "29.1" + Task = "Turn off Windows Update" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DoNotConnectToWindowsUpdateInternetLocations" ` + | Select-Object -ExpandProperty "DoNotConnectToWindowsUpdateInternetLocations" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "29.2" + Task = "Turn off Windows Update" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DisableWindowsUpdateAccess" ` + | Select-Object -ExpandProperty "DisableWindowsUpdateAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "29.3" + Task = "Turn off Windows Update" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "WUServer" ` + | Select-Object -ExpandProperty "WUServer" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "29.4" + Task = "Turn off Windows Update" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "WUStatusServer" ` + | Select-Object -ExpandProperty "WUStatusServer" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "29.5" + Task = "Turn off Windows Update" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "UpdateServiceUrlAlternate" ` + | Select-Object -ExpandProperty "UpdateServiceUrlAlternate" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "29.6" + Task = "Turn off Windows Update" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "UseWUServer" ` + | Select-Object -ExpandProperty "UseWUServer" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#AccountPolicies.ps1 new file mode 100644 index 0000000..ee46aa7 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#AccountPolicies.ps1 @@ -0,0 +1,255 @@ +[AuditTest] @{ + Id = "200" + Task = "(ND, NE) Ensure 'Store passwords using reversible encryption' is set to 'Disabled'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "201" + Task = "(ND, NE) Ensure 'Password must meet complexity requirements' is set to 'Enabled'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "202" + Task = "(ND, NE) Ensure 'Enforce password history' is set to '24 or more password(s)'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "203" + Task = "(ND, NE) Ensure 'Maximum password age' is set to '365 or fewer days, but not 0'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 365 -or $setPolicy -le 0)) { + if($setPolicy -eq -1){ #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 365 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "204" + Task = "(ND, NE) Ensure 'Minimum password length' is set to '14 or more character(s)'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "205" + Task = "(ND, NE) Ensure 'Minimum password age' is set to '1 or more day(s)' ." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 1)) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "206" + Task = "(ND) Ensure 'Account lockout duration' is set to '15 or more minute(s)'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "207" + Task = "(ND) Ensure 'Account lockout threshold' is set to '10 or fewer invalid logon attempt(s), but not 0'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 10 -or $setPolicy -le 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 10 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "208" + Task = "(ND) Ensure 'Reset account lockout counter after' is set to '15 or`nmore minute(s)'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#AuditPolicies.ps1 new file mode 100644 index 0000000..346e5c7 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#AuditPolicies.ps1 @@ -0,0 +1,77 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#RegistrySettings.ps1 new file mode 100644 index 0000000..dc5400c --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#RegistrySettings.ps1 @@ -0,0 +1,12419 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$avstatus = CheckForActiveAV +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "1" + Task = "(ND, NE) Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2" + Task = "(ND, NE) Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3" + Task = "(ND, NE) Ensure 'Configure SMB v1 server' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4" + Task = "(ND, NE) Ensure 'Enable Structured Exception Handling OverwriteProtection (SEHOP)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5" + Task = "(ND, NE) Ensure 'WDigest Authentication' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "7" + Task = "(ND, NE) Ensure 'MSS: (EnableDeadGWDetect) Allow automatic detection of dead network gateways (could lead to DoS)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableDeadGWDetect" ` + | Select-Object -ExpandProperty "EnableDeadGWDetect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8" + Task = "(ND, NE) Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon(not recommended)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9" + Task = "(ND, NE) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routingprotection level (protects against packet spoofing)' is set to 'Enabled:Highest protection, source routing is completely disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "10" + Task = "(ND, NE) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled:Highest protection, source routing is completely disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "11" + Task = "(HD) Ensure 'MSS: (DisableSavePassword) Prevent the dial-up password from being saved' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\RasMan\Parameters" ` + -Name "disablesavepassword" ` + | Select-Object -ExpandProperty "disablesavepassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "12" + Task = "(ND, NE) Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "13" + Task = "(HD) Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "KeepAliveTime" ` + | Select-Object -ExpandProperty "KeepAliveTime" + + if ($regValue -ne 300000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 300000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "14" + Task = "(ND, NE) Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\netBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "15" + Task = "(HD) Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "PerformRouterDiscovery" ` + | Select-Object -ExpandProperty "PerformRouterDiscovery" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "16" + Task = "(ND, NE) Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "17" + Task = "(ND, NE) Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScreenSaverGracePeriod" ` + | Select-Object -ExpandProperty "ScreenSaverGracePeriod" + + if ($regValue -notmatch "^[0-5]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[0-5]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18" + Task = "(HD) Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19" + Task = "(HD) Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "20" + Task = "(ND, NE) Ensure 'Turn off multicast name resolution' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "21" + Task = "(ND, NE) Ensure 'NetBIOS node type' is set to 'P-node'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\netbt\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "22" + Task = "(ND, NE) Ensure 'Enable insecure guest logons' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "23" + Task = "(HD) Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Peernet" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24 A" + Task = "(ND, NE) Ensure 'Hardened UNC Paths' is set to `"Require Mutual Authentication=1, `"Require Integrity=1`" for the value names `"\\*\NETLOGON`" und `"\\*\SYSVOL`". [\\*\NETLOGON]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if ($regValue -eq $null) { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object { $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24 B" + Task = "(ND, NE) Ensure 'Hardened UNC Paths' is set to `"Require Mutual Authentication=1, `"Require Integrity=1`" for the value names `"\\*\NETLOGON`" und `"\\*\SYSVOL`". [\\*\SYSVOL]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if ($regValue -eq $null) { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object { $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "25" + Task = "(ND) Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_StdDomainUserSetLocation" ` + | Select-Object -ExpandProperty "NC_StdDomainUserSetLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "26" + Task = "(ND) Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "27" + Task = "(ND) Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "28" + Task = "(HD) Ensure 'Enable Font Providers' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableFontProviders" ` + | Select-Object -ExpandProperty "EnableFontProviders" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "29" + Task = "(HD) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableRspndr" ` + | Select-Object -ExpandProperty "EnableRspndr" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "30" + Task = "(HD) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableLLTDIO" ` + | Select-Object -ExpandProperty "EnableLLTDIO" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "31" + Task = "(HD) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "EnableRegistrars" ` + | Select-Object -ExpandProperty "EnableRegistrars" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "32" + Task = "(HD) Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\UI" ` + -Name "DisableWcnUi" ` + | Select-Object -ExpandProperty "DisableWcnUi" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "33" + Task = "(ND, NE) Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to the value 'Enabled: 1 = Minimize the number of simultaneous connections'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fMinimizeConnections" ` + | Select-Object -ExpandProperty "fMinimizeConnections" + + if ($null -eq $regValue -or 0 -eq $regValue) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1-3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "34" + Task = "(ND) Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($regValue -eq 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "35" + Task = "(ND, NE) Ensure 'Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config" ` + -Name "AutoConnectAllowedOEM" ` + | Select-Object -ExpandProperty "AutoConnectAllowedOEM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "36" + Task = "(HD) Ensure 'Turn off notifications network usage' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "37" + Task = "(ND, NE) Ensure 'Turn off toast notifications on the lock screen' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "38" + Task = "(HD) Ensure 'Turn off Help Experience Improvement Program' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Assistance\Client\1.0" ` + -Name "NoImplicitFeedback" ` + | Select-Object -ExpandProperty "NoImplicitFeedback" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "39" + Task = "(ND, NE) Ensure 'Turn off picture password sign-in' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "BlockDomainPicturePassword" ` + | Select-Object -ExpandProperty "BlockDomainPicturePassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "40" + Task = "(ND, NE) Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "41" + Task = "(ND, NE) Ensure 'Block user from showing account details on signin' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockUserFromShowingAccountDetailsOnSignin" ` + | Select-Object -ExpandProperty "BlockUserFromShowingAccountDetailsOnSignin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "42" + Task = "(ND) Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "43" + Task = "(ND) Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "44" + Task = "(ND, NE) Ensure 'Do not display network selection UI' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "45" + Task = "(ND) Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontEnumerateConnectedUsers" ` + | Select-Object -ExpandProperty "DontEnumerateConnectedUsers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "46" + Task = "(ND, NE) Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "47" + Task = "(HD) Ensure 'Turn off the advertising ID' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" ` + -Name "DisabledByGroupPolicy" ` + | Select-Object -ExpandProperty "DisabledByGroupPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "48" + Task = "(HD) Ensure 'Allow upload of User Activities' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "UploadUserActivities" ` + | Select-Object -ExpandProperty "UploadUserActivities" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "49" + Task = "(HD) Ensure 'Allow Clipboard synchronization across devices' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowCrossDeviceClipboard" ` + | Select-Object -ExpandProperty "AllowCrossDeviceClipboard" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "50" + Task = "(ND, NE) Ensure 'Encryption Oracle Remediation' is set to 'Enabled: Force Updated Clients'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "51" + Task = "(ND) Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "52" + Task = "(ND, NE) Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled' ." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "53" + Task = "(ND, NE) Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "54" + Task = "(ND, NE) Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "55" + Task = "(ND, NE) Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "56" + Task = "(ND, NE) Ensure 'Allow standby states (S1-S3) when sleeping (on battery)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "57" + Task = "(ND, NE) Ensure 'Allow standby states (S1-S3) when sleeping (plugged in)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "58" + Task = "(HD) Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Control Panel\International" ` + -Name "BlockUserInputMethodsForSignIn" ` + | Select-Object -ExpandProperty "BlockUserInputMethodsForSignIn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "59 A" + Task = "(ND, NE) Ensure 'Prevent installation of devices that match any of these device IDs' is configured." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceIDs" ` + | Select-Object -ExpandProperty "DenyDeviceIDs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "59 B" + Task = "(ND, NE) Ensure 'Prevent installation of devices that match any of these device IDs' is configured. (PCI\CC_0C0A)" + Test = { + try { + $valueNames = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceIDs" + + $expectedValue = "PCI\CC_0C0A" + + foreach ($obj in $valueNames.PSObject.Properties) { + if ($obj.Value -eq $expectedValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Registry value is missing: $expectedValue" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "59 C" + Task = "(ND, NE) Ensure 'Prevent installation of devices that match any of these device IDs' is configured. (DenyDeviceIDsRetroactive)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceIDsRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceIDsRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "60 A" + Task = "(ND, NE) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClasses" ` + | Select-Object -ExpandProperty "DenyDeviceClasses" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "60 B" + Task = "(ND, NE) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured. (Blocking the SBP-2 driver and Thunderbolt controllers to reduce 1394 DMA and Thunderbolt DMA threats to BitLocker)" + Test = { + try { + $valueNames = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" + + $expectedValue = "{d48179be-ec20-11d1-b6b8-00c04fa372a7}" + + foreach ($obj in $valueNames.PSObject.Properties) { + if ($obj.Value -eq $expectedValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Registry value is missing: $expectedValue" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "60 C" + Task = "(ND, NE) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured. (IEEE 1394 Devices That Support the 61883 Protocol)" + Test = { + try { + $valueNames = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" + + $expectedValue = "{7ebefbc0-3200-11d2-b4c2-00a0C9697d07}" + + foreach ($obj in $valueNames.PSObject.Properties) { + if ($obj.Value -eq $expectedValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Registry value is missing: $expectedValue" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "60 D" + Task = "(ND, NE) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured. (IEEE 1394 Devices That Support the AVC Protocol)" + Test = { + try { + $valueNames = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" + + $expectedValue = "{c06ff265-ae09-48f0-812c-16753d7cba83}" + + foreach ($obj in $valueNames.PSObject.Properties) { + if ($obj.Value -eq $expectedValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Registry value is missing: $expectedValue" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "60 E" + Task = "(ND, NE) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured. (IEEE 1394 Host Bus Controller)" + Test = { + try { + $valueNames = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" + + $expectedValue = "{6bdd1fc1-810f-11d0-bec7-08002be2092f}" + + foreach ($obj in $valueNames.PSObject.Properties) { + if ($obj.Value -eq $expectedValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Registry value is missing: $expectedValue" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "60 F" + Task = "(ND, NE) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured. (DenyDeviceClassesRetroactive)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClassesRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceClassesRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "61" + Task = "(ND, NE) Ensure 'Continue experiences on this device' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableCdp" ` + | Select-Object -ExpandProperty "EnableCdp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "62" + Task = "(ND) Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableBkGndGroupPolicy" ` + | Select-Object -ExpandProperty "DisableBkGndGroupPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "63" + Task = "(ND) Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "64" + Task = "(ND) Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "65" + Task = "(ND) Ensure 'Configure security policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "66" + Task = "(HD) Ensure 'Turn off the `"Order Prints`" picture task' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoOnlinePrintsWizard" ` + | Select-Object -ExpandProperty "NoOnlinePrintsWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "67" + Task = "(HD) Ensure 'Turn off the `"Publish to Web`" task for files and folders' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoPublishingWizard" ` + | Select-Object -ExpandProperty "NoPublishingWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "68" + Task = "(ND, NE) Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "69" + Task = "(HD) Ensure 'Turn off printing over HTTP' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "70" + Task = "(HD) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "71" + Task = "(HD) Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TabletPC" ` + -Name "PreventHandwritingDataSharing" ` + | Select-Object -ExpandProperty "PreventHandwritingDataSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "72" + Task = "(HD) Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HandwritingErrorReports" ` + -Name "PreventHandwritingErrorReports" ` + | Select-Object -ExpandProperty "PreventHandwritingErrorReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "73" + Task = "(HD) Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SearchCompanion" ` + -Name "DisableContentFileUpdates" ` + | Select-Object -ExpandProperty "DisableContentFileUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "74" + Task = "(ND, NE) Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "75" + Task = "(HD) Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Messenger\Client" ` + -Name "CEIP" ` + | Select-Object -ExpandProperty "CEIP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "76" + Task = "(HD) Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SQMClient\Windows" ` + -Name "CEIPEnable" ` + | Select-Object -ExpandProperty "CEIPEnable" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "77" + Task = "(HD) Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Registration Wizard Control" ` + -Name "NoRegistration" ` + | Select-Object -ExpandProperty "NoRegistration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "78" + Task = "(HD) Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Internet Connection Wizard" ` + -Name "ExitOnMSICW" ` + | Select-Object -ExpandProperty "ExitOnMSICW" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "79" + Task = "(HD) Ensure 'Turn off access to the Store' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoUseStoreOpenWith" ` + | Select-Object -ExpandProperty "NoUseStoreOpenWith" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "80" + Task = "(HD) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "DevicePKInitBehavior" ` + | Select-Object -ExpandProperty "DevicePKInitBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "81" + Task = "(ND, NE) Ensure 'Enumeration policy for external devices incompatible with Kernel DMA Protection' is set to 'Enabled: Block All'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "82" + Task = "(HD) Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled' ." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "83" + Task = "(HD) Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d}" ` + -Name "ScenarioExecutionEnabled" ` + | Select-Object -ExpandProperty "ScenarioExecutionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "84" + Task = "(ND, NE) Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' ." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "85" + Task = "(ND, NE) Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "EnableAuthEpResolution" ` + | Select-Object -ExpandProperty "EnableAuthEpResolution" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "86" + Task = "(ND, NE) Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "87" + Task = "(ND, NE) Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "88" + Task = "(ND, NE) Ensure 'Ignore the default list of blocked TPM commands' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\TPM\BlockedCommands" ` + -Name "IgnoreDefaultList" ` + | Select-Object -ExpandProperty "IgnoreDefaultList" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "89" + Task = "(ND, NE) Ensure 'Standard User Lockout Duration' is set to '30 minutes'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Tpm" ` + -Name "StandardUserAuthorizationFailureDuration" ` + | Select-Object -ExpandProperty "StandardUserAuthorizationFailureDuration" + + if ($regValue -ne 30) { + return @{ + Message = "Registry value is '$regValue'. Expected: 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "90" + Task = "(ND, NE) Ensure 'Standard User Total Lockout Threshold' is set to '5'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Tpm" ` + -Name "StandardUserAuthorizationFailureIndividualThreshold" ` + | Select-Object -ExpandProperty "StandardUserAuthorizationFailureIndividualThreshold" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "91" + Task = "(HD) Ensure 'Enable Windows NTP Client' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "92" + Task = "(HD) Ensure 'Enable Windows NTP Server' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "93" + Task = "(HD) Ensure 'Allow Online Tips' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "AllowOnlineTips" ` + | Select-Object -ExpandProperty "AllowOnlineTips" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "94" + Task = "(ND, NE) Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "95" + Task = "(ND, NE) Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "96" + Task = "(ND, NE) Ensure 'Force specific screen saver: Screen saver executable name' is set to 'Enabled: scrnsave.scr'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "SCRNSAVE.EXE" ` + | Select-Object -ExpandProperty "SCRNSAVE.EXE" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "97" + Task = "(ND, NE) Ensure 'Enable screen saver' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaveActive" ` + | Select-Object -ExpandProperty "ScreenSaveActive" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "98" + Task = "(ND, NE) Ensure 'Password protect the screen saver' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaverIsSecure" ` + | Select-Object -ExpandProperty "ScreenSaverIsSecure" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "99" + Task = "(ND, NE) Ensure 'Screen saver timeout' is set to 'Enabled: 900 seconds or fewer, but not 0'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaveTimeOut" ` + | Select-Object -ExpandProperty "ScreenSaveTimeOut" + + if (($regValue -gt 900 -or $regValue -le 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x > 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "100 A" + Task = "(ND, NE) Ensure 'Turn off automatic learning' is set to 'Enabled' for ImplicitTextCollection." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "RestrictImplicitTextCollection" ` + | Select-Object -ExpandProperty "RestrictImplicitTextCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "100 B" + Task = "(ND, NE) Ensure 'Turn off automatic learning' is set to 'Enabled' for ImplicitInkCollection." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "RestrictImplicitInkCollection" ` + | Select-Object -ExpandProperty "RestrictImplicitInkCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "101" + Task = "(ND, NE) Ensure 'Allow users to enable online speech recognition services' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "AllowInputPersonalization" ` + | Select-Object -ExpandProperty "AllowInputPersonalization" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "102" + Task = "(ND, NE) Ensure 'Notify antivirus programs when opening attachments' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "ScanWithAntiVirus" ` + | Select-Object -ExpandProperty "ScanWithAntiVirus" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "103" + Task = "(ND, NE) Ensure 'Do not preserve zone information in file attachments' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "104" + Task = "(HD) Ensure 'Block launching Universal Windows apps with Windows Runtime API access from hosted content.' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "BlockHostedAppAccessWinRT" ` + | Select-Object -ExpandProperty "BlockHostedAppAccessWinRT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "105" + Task = "(ND) Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "106" + Task = "(ND, NE) Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "107" + Task = "(ND, NE) Ensure 'Do not display the password reveal button' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "108" + Task = "(HD) Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager" ` + -Name "AllowSharedLocalAppData" ` + | Select-Object -ExpandProperty "AllowSharedLocalAppData" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "109" + Task = "(ND, NE) Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "110" + Task = "(HD) Ensure 'Turn off all Windows spotlight features' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsSpotlightFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsSpotlightFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "111" + Task = "(HD) Ensure 'Do not use diagnostic data for tailored experiences' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableTailoredExperiencesWithDiagnosticData" ` + | Select-Object -ExpandProperty "DisableTailoredExperiencesWithDiagnosticData" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "112" + Task = "(ND, NE) Ensure 'Do not suggest third-party content in Windows spotlight' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "113" + Task = "(ND, NE) Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "114" + Task = "(ND, NE) Ensure 'Configure Windows spotlight on lock screen' is set to Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "ConfigureWindowsSpotlight" ` + | Select-Object -ExpandProperty "ConfigureWindowsSpotlight" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "115" + Task = "(ND, NE) Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "116" + Task = "(ND, NE) Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "117" + Task = "(ND, NE) Ensure 'Turn off heap termination on corruption' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "118" + Task = "(ND, NE) Ensure 'Toggle user control over Insider builds' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" ` + -Name "AllowBuildPreview" ` + | Select-Object -ExpandProperty "AllowBuildPreview" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "119" + Task = "(ND, NE) Ensure 'Do not show feedback notifications' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DoNotShowFeedbackNotifications" ` + | Select-Object -ExpandProperty "DoNotShowFeedbackNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "120" + Task = "(ND, NE) Ensure 'Allow Telemetry' is set to 'Enabled: 0 - Security [Enterprise Only] or Enabled: 1 - Basic'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + $saferClients = @("*Server*", "*Education*", "*Enterprise*") + $productname = Get-ComputerInfo | select -ExpandProperty OsName + if (($productname -notcontains $saferClients) -and ($regValue -eq 1)) { + return @{ + Message = "Registry value is '$regValue'. Your OS $productname does not support 'Diagnostic data off'." + Status = "Warning" + } + } + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "121" + Task = "(ND, NE) Ensure 'Allow device name to be sent in Windows diagnostic data' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowDeviceNameInTelemetry" ` + | Select-Object -ExpandProperty "AllowDeviceNameInTelemetry" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "122" + Task = "(HD) Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableEnterpriseAuthProxy" ` + | Select-Object -ExpandProperty "DisableEnterpriseAuthProxy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "123" + Task = "(HD) Ensure 'Allow Use of Camera' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera" ` + -Name "AllowCamera" ` + | Select-Object -ExpandProperty "AllowCamera" + + if ($regValue -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam" ` + -Name "Value" ` + | Select-Object -ExpandProperty "Value" + + if ($regValue -match "Deny") { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Camera is not deactivated." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "124" + Task = "(ND, NE) Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount" ` + -Name "DisableUserAuth" ` + | Select-Object -ExpandProperty "DisableUserAuth" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "125" + Task = "(HD) Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging" ` + -Name "AllowMessageSync" ` + | Select-Object -ExpandProperty "AllowMessageSync" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "126" + Task = "(ND, NE) Ensure 'Prevent users from sharing files within their profile.' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInplaceSharing" ` + | Select-Object -ExpandProperty "NoInplaceSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "127" + Task = "(ND, NE) Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "128" + Task = "(HD) Ensure 'Turn off location' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "129" + Task = "(HD) Ensure 'Turn off Push To Install service' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall" ` + -Name "DisablePushToInstall" ` + | Select-Object -ExpandProperty "DisablePushToInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "130" + Task = "(HD) Ensure 'Do not allow COM port redirection' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCcm" ` + | Select-Object -ExpandProperty "fDisableCcm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "131" + Task = "(ND, NE) Ensure 'Do not allow drive redirection' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "132" + Task = "(HD) Ensure 'Do not allow LPT port redirection' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLPT" ` + | Select-Object -ExpandProperty "fDisableLPT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "133" + Task = "(HD) Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisablePNPRedir" ` + | Select-Object -ExpandProperty "fDisablePNPRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "134" + Task = "(ND, NE) Ensure 'Always prompt for password upon connection' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "135" + Task = "(ND, NE) Ensure 'Require user authentication for remote connections by using Network Level Authentication' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "UserAuthentication" ` + | Select-Object -ExpandProperty "UserAuthentication" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "136" + Task = "(ND, NE) Ensure 'Require secure RPC communication' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "137" + Task = "(ND, NE) Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "138" + Task = "(ND, NE) Ensure 'Require use of specific security layer for remote (RDP) connections' is set to 'Enabled: SSL'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SecurityLayer" ` + | Select-Object -ExpandProperty "SecurityLayer" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "139" + Task = "(ND, NE) Ensure 'End session when time limits are reached' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fResetBroken" ` + | Select-Object -ExpandProperty "fResetBroken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "140" + Task = "(HD) Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxIdleTime" ` + | Select-Object -ExpandProperty "MaxIdleTime" + + if (($regValue -gt 900000 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900000 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "141" + Task = "(HD) Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxDisconnectionTime" ` + | Select-Object -ExpandProperty "MaxDisconnectionTime" + + if ($regValue -ne 60000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 60000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "142" + Task = "(ND, NE) Ensure 'Do not use temporary folders per session' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "PerSessionTempDir" ` + | Select-Object -ExpandProperty "PerSessionTempDir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "143" + Task = "(ND, NE) Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "144" + Task = "(HD) Ensure 'Allow users to connect remotely by using Remote Desktop Services' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDenyTSConnections" ` + | Select-Object -ExpandProperty "fDenyTSConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "145" + Task = "(ND, NE) Ensure 'Do not allow passwords to be saved' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "146" + Task = "(ND, NE) Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "147" + Task = "(ND, NE) Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "148" + Task = "(ND, NE) Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "149" + Task = "(ND, NE) Ensure 'Prevent downloading of enclosures' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "150" + Task = "(HD) Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" ` + -Name "NoGenTicket" ` + | Select-Object -ExpandProperty "NoGenTicket" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "151" + Task = "(HD) Ensure 'Disable all apps from Microsoft Store' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "DisableStoreApps" ` + | Select-Object -ExpandProperty "DisableStoreApps" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "152" + Task = "(ND, NE) Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "AutoDownload" ` + | Select-Object -ExpandProperty "AutoDownload" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "153" + Task = "(ND, NE) Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "DisableOSUpgrade" ` + | Select-Object -ExpandProperty "DisableOSUpgrade" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "154" + Task = "(HD) Ensure 'Only display the private store within the Microsoft Store' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "RequirePrivateStoreOnly" ` + | Select-Object -ExpandProperty "RequirePrivateStoreOnly" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "155" + Task = "(HD) Ensure 'Turn off the Store application' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "RemoveWindowsStore" ` + | Select-Object -ExpandProperty "RemoveWindowsStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "156" + Task = "(HD) Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCloudSearch" ` + | Select-Object -ExpandProperty "AllowCloudSearch" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "157" + Task = "(ND, NE) Ensure 'Allow search and Cortana to use location' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowSearchToUseLocation" ` + | Select-Object -ExpandProperty "AllowSearchToUseLocation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "158" + Task = "(ND, NE) Ensure 'Allow indexing of encrypted files' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "159" + Task = "(ND, NE) Ensure 'Improve inking and typing recognition' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\TextInput" ` + -Name "AllowLinguisticDataCollection" ` + | Select-Object -ExpandProperty "AllowLinguisticDataCollection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "160" + Task = "(ND, NE) Ensure 'Download Mode' is set to 'Enabled: Simple (99)' ." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization" ` + -Name "DODownloadMode" ` + | Select-Object -ExpandProperty "DODownloadMode" + + if ($regValue -ne 99) { + return @{ + Message = "Registry value is '$regValue'. Expected: 99" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "161" + Task = "(ND, NE) Ensure 'Require pin for pairing' is set to 'Enabled: Always'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect" ` + -Name "RequirePinForPairing" ` + | Select-Object -ExpandProperty "RequirePinForPairing" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "162" + Task = "(ND, NE) Ensure 'Configure detection for potentially unwanted applications' is set to 'Enabled: Block'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "163" + Task = "(ND, NE) Ensure 'Turn off Windows Defender Antivirus' is set to 'Disabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender" ` + -Name "DisableAntiSpyware" ` + | Select-Object -ExpandProperty "DisableAntiSpyware" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "164" + Task = "(ND, NE) Ensure 'Configure Watson events' is set to 'Disabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Reporting" ` + -Name "DisableGenericReports" ` + | Select-Object -ExpandProperty "DisableGenericReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "165" + Task = "(ND, NE) Ensure 'Turn on behavior monitoring' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "166" + Task = "(HD) Ensure 'Join Microsoft MAPS' is set to 'Disabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "167" + Task = "(ND, NE) Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "168" + Task = "(ND, NE) Ensure 'Turn on e-mail scanning' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "169" + Task = "(ND, NE) Ensure 'Scan removable drives' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "170" + Task = "(ND, NE) Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "171" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 A" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office communication application from creating child processes)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 B" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from creating executable content)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 C" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block execution of potentially obfuscated scripts)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 D" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from injecting code into other processes)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 E" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Adobe Reader from creating child processes)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 F" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Win32 API calls from Office macro)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 G" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block credential stealing from the Windows local security authority subsystem (lsass.exe))" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 H" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block untrusted and unsigned processes that run from USB)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 I" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block executable content from email client and webmail)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 J" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block JavaScript or VBScript from launching downloaded executable content)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 K" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from creating child processes)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "173" + Task = "(ND, NE) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "174" + Task = "(ND, NE) Ensure 'Prevent bypassing Windows Defender SmartScreen prompts for sites' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "175" + Task = "(ND, NE) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "176" + Task = "(HD) Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowSuggestedAppsInWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowSuggestedAppsInWindowsInkWorkspace" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "177" + Task = "(ND, NE) Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if (($regValue -ne 1) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "178" + Task = "(ND, NE) Ensure 'Allow user control over installs' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "179" + Task = "(HD) Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "180" + Task = "(ND, NE) Ensure 'Always install with elevated privileges' is set to 'Disabled' on local_machine." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "181" + Task = "(ND, NE) Ensure 'Always install with elevated privileges' is set to 'Disabled' on current_user." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "182" + Task = "(HD) Ensure 'Prevent Codec Download' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\WindowsMediaPlayer" ` + -Name "PreventCodecDownload" ` + | Select-Object -ExpandProperty "PreventCodecDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "184" + Task = "(HD) Ensure 'Turn on Script Execution' is set to 'Enabled: Allow only signed scripts'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\PowerShell" ` + -Name "ExecutionPolicy" ` + | Select-Object -ExpandProperty "ExecutionPolicy" + + if ($regValue -ne "AllSigned") { + return @{ + Message = "Registry value is '$regValue'. Expected: AllSigned" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "185" + Task = "(ND, NE) Ensure 'Configure Automatic Updates' is set to 'Enabled: 4 Auto download and schedule the install'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "186" + Task = "(ND, NE) Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "187" + Task = "(ND, NE) Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "188" + Task = "(ND, NE) Ensure 'Remove access to `"Pause updates`" feature' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "SetDisablePauseUXAccess" ` + | Select-Object -ExpandProperty "SetDisablePauseUXAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "189" + Task = "(ND, NE) Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "190" + Task = "(HD) Ensure 'Allow Remote Shell Access' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service\WinRS" ` + -Name "AllowRemoteShellAccess" ` + | Select-Object -ExpandProperty "AllowRemoteShellAccess" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "191" + Task = "(ND, NE) Ensure 'Allow Basic authentication' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "192" + Task = "(ND, NE) Ensure 'Disallow Digest authentication' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "193" + Task = "(ND, NE) Ensure 'Allow unencrypted traffic' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "194" + Task = "(ND, NE) Ensure 'Allow Basic authentication' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "195" + Task = "(HD) Ensure 'Allow remote server management through WinRM' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowAutoConfig" ` + | Select-Object -ExpandProperty "AllowAutoConfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "196" + Task = "(ND, NE) Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "197" + Task = "(ND, NE) Ensure 'Allow unencrypted traffic' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "198" + Task = "(ND, NE) Ensure 'Prevent users from modifying settings' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender Security Center\App and Browser protection" ` + -Name "DisallowExploitProtectionOverride" ` + | Select-Object -ExpandProperty "DisallowExploitProtectionOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "199" + Task = "(ND, NE) Ensure 'Enables or disables Windows Game Recording and Broadcasting' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR" ` + -Name "AllowGameDVR" ` + | Select-Object -ExpandProperty "AllowGameDVR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "209" + Task = "(ND, NE) Configure 'Interactive logon: Message title for users attempting to log on'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "210" + Task = "(ND, NE) Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "211" + Task = "(ND, NE) Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "212" + Task = "(ND, NE) Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "213" + Task = "(ND, NE) Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "214" + Task = "(ND, NE) Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "215" + Task = "(ND, NE) Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "216" + Task = "(ND, NE) Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableUIADesktopToggle" ` + | Select-Object -ExpandProperty "EnableUIADesktopToggle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "217" + Task = "(ND, NE) Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "218" + Task = "(ND, NE) Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Prompt for credentials on the secure desktop'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "219" + Task = "(ND) Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "220" + Task = "(ND) Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "221" + Task = "(ND) Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "222" + Task = "(ND) Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "223" + Task = "(ND) Ensure 'Domain member: Maximum machine account password age' is set to '30 or fewer days, but not 0'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if (($regValue -le 0 -or $regValue -gt 30)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x > 0 and x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "224" + Task = "(ND) Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "225" + Task = "(HD) Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "226" + Task = "(ND, NE) Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators and Interactive Users'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AllocateDASD" ` + | Select-Object -ExpandProperty "AllocateDASD" + + if ($regValue -ne "2") { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "227" + Task = "(ND, NE) Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if (($regValue -gt 14 -or $regValue -lt 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 14 and x >= 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "228" + Task = "(HD) Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "CachedLogonsCount" ` + | Select-Object -ExpandProperty "CachedLogonsCount" + + if ($regValue -notmatch "^[43210]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[43210]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "229" + Task = " Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "230" + Task = "(ND, NE) Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "231" + Task = "(ND, NE) Configure 'Interactive logon: Message text for users attempting to log on'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "232" + Task = "(ND) Ensure 'Interactive logon: Machine account lockout threshold' is set to '10 or fewer invalid logon attempts, but not 0'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MaxDevicePasswordFailedAttempts" ` + | Select-Object -ExpandProperty "MaxDevicePasswordFailedAttempts" + + if (($regValue -gt 10 -or $regValue -le 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 10 and x > 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "233" + Task = "(ND) Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -notmatch "^(1|2|3)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(1|2|3)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "234" + Task = "(ND, NE) Ensure 'Interactive logon: Don't display last signed-in' is setto 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "239" + Task = "(ND, NE) Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "240" + Task = "(ND, NE) Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "NoConnectedUser" ` + | Select-Object -ExpandProperty "NoConnectedUser" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "241" + Task = "(ND, NE) Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'." + Test = { + try { + if ((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "242" + Task = "(ND, NE) Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'." + Test = { + try { + if ((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True) { + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "243" + Task = "(ND, NE) Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "244" + Task = "(ND, NE) Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "enableforcedlogoff" ` + | Select-Object -ExpandProperty "enableforcedlogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "245" + Task = "(ND, NE) Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'." + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See
here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "246" + Task = "(ND, NE) Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'. " + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True) { + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "247" + Task = "(ND, NE) Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s)'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if (($regValue -gt 15)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "248" + Task = "(ND) Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "SMBServerNameHardeningLevel" ` + | Select-Object -ExpandProperty "SMBServerNameHardeningLevel" + + if (($regValue -lt 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "250" + Task = "(HD) Ensure 'Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers' is set to 'Deny all'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "RestrictSendingNTLMTraffic" ` + | Select-Object -ExpandProperty "RestrictSendingNTLMTraffic" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "251" + Task = "(HD) Ensure 'Network security: Restrict NTLM: Incoming NTLM traffic' is set to 'Deny all accounts'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "RestrictReceivingNTLMTraffic" ` + | Select-Object -ExpandProperty "RestrictReceivingNTLMTraffic" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "252" + Task = "(ND) Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "253" + Task = "(ND, NE) Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "254" + Task = "(ND, NE) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "255" + Task = "(ND, NE) Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "256" + Task = "(ND, NE) Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "257" + Task = "(ND) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "258" + Task = "(ND) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "259" + Task = "(ND) Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if (($regValue -lt 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "260" + Task = "(ND, NE) Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "261" + Task = "(ND, NE) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "262" + Task = "(ND) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "264" + Task = "(ND, NE) Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "265" + Task = "(ND, NE) Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "restrictremotesam" ` + | Select-Object -ExpandProperty "restrictremotesam" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "266" + Task = "(ND) Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "267" + Task = "(ND, NE) Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionShares" ` + | Select-Object -ExpandProperty "NullSessionShares" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "268" + Task = "(ND, NE) Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "269" + Task = "(ND, NE) Ensure 'Network access: Named Pipes that can be accessed anonymously' is set to 'None'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "270" + Task = "(ND, NE) Configure 'Network access: Remotely accessible registry paths and sub-paths'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "271" + Task = "(ND, NE) Configure 'Network access: Remotely accessible registry paths'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\ProductOptions" + "System\CurrentControlSet\Control\Server Applications" + "Software\Microsoft\Windows NT\CurrentVersion" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\ProductOptions System\CurrentControlSet\Control\Server Applications Software\Microsoft\Windows NT\CurrentVersion" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "272" + Task = "(ND, NE) Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "273" + Task = "(HD) Ensure 'System settings: Optional subsystems' is set to 'None'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems" ` + -Name "Optional" ` + | Select-Object -ExpandProperty "Optional" + + if ($regValue -ne $null) { + return @{ + Message = "Registry value is '$regValue'. Expected: (Blank)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "274" + Task = "(HD) Ensure 'System cryptography: Force strong key protection for user keys stored on the computer' is set to 'User is prompted when the key is first used'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography" ` + -Name "ForceKeyProtection" ` + | Select-Object -ExpandProperty "ForceKeyProtection" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "275" + Task = "(ND, NE) Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "276" + Task = "(ND, NE) Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "316" + Task = "(HD) Ensure 'Remote Desktop Services UserMode Port Redirector (UmRdpService)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UmRdpService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "317" + Task = "(ND, NE) Ensure 'Connected User Experiences and Telemetry' is set to 'Disabled'." + Test = { + try { + $status = Get-Service DiagTrack -ErrorAction Stop | select -property starttype + if ($status.StartType -ne "Disabled") { + return @{ + Message = "Service not compliant. Currently: $($status)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + catch [System.SystemException] { + return @{ + Message = "Service not found!" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "318" + Task = "(HD) Ensure 'Bluetooth Audio Gateway Service (BTAGService)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTAGService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "319" + Task = "(HD) Ensure 'Bluetooth Support Service (bthserv)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bthserv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "320" + Task = "(ND, NE) Ensure 'Computer Browser (Browser)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "321" + Task = "(NE, ND) Ensure 'Internet Connection Sharing (ICS) (SharedAccess)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "322" + Task = "(HD) Ensure 'Geolocation Service (lfsvc)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lfsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "323" + Task = "(ND, NE) Ensure 'IIS Admin Service (IISADMIN)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IISADMIN" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "324" + Task = "(NE, ND) Ensure 'Infrared monitor service (irmon)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\irmon" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "325" + Task = "(HD) Ensure 'Remote Desktop Configuration (SessionEnv)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SessionEnv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "326" + Task = "(ND, NE) Ensure 'LxssManager (LxssManager)' is set to 'Disabled' or 'Not Installed'." + Test = { + $result = Get-WindowsOptionalFeature -online -FeatureName Microsoft-Windows-Subsystem-Linux + $state = $result.State + if ($state -eq "Disabled" -or $state -eq "Not Installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + else { + return @{ + Message = "Registry value is '$state'. Expected: 'Disabled' or 'Not Installed'" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "327" + Task = "(HD) Ensure 'Downloaded Maps Manager (MapsBroker)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MapsBroker" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "328" + Task = "(ND, NE) Ensure 'Microsoft FTP Service (FTPSVC)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FTPSVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "329" + Task = "(HD) Ensure 'Microsoft iSCSI Initiator Service (MSiSCSI)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSiSCSI" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "330" + Task = "(HD) Ensure 'Microsoft Store Install Service (InstallService)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\InstallService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "331" + Task = "(ND, NE) Ensure 'OpenSSH SSH Server (sshd)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sshd" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "332" + Task = "(HD) Ensure 'Peer Name Resolution Protocol (PNRPsvc)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "333" + Task = "(HD) Ensure 'Peer Networking Grouping (p2psvc)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2psvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "334" + Task = "(HD) Ensure 'Peer Networking Identity Manager (p2pimsvc)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2pimsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "335" + Task = "(HD) Ensure 'PNRP Machine Name Publication Service (PNRPAutoReg)' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPAutoReg" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "336" + Task = "(HD) Ensure 'Remote Desktop Services (TermService)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "337" + Task = "(HD) Ensure 'Remote Registry (RemoteRegistry)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteRegistry" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "338" + Task = "(ND, NE) Ensure 'Routing and Remote Access (RemoteAccess)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "339" + Task = "(ND, NE) Ensure 'Remote Procedure Call (RPC) Locator (RpcLocator)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcLocator" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "340" + Task = "(HD) Ensure 'Server (LanmanServer)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "341" + Task = "(ND, NE) Ensure 'Simple TCP/IP Services (simptcp)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\simptcp" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "342" + Task = "(HD) Ensure 'SNMP Service (SNMP)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SNMP" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "343" + Task = "(ND, NE) Ensure 'SSDP Discovery (SSDPSRV)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SSDPSRV" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "344" + Task = "(HD) Ensure 'Problem Reports and Solutions Control Panel Support (wercplsupport)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wercplsupport" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "345" + Task = "(ND, NE) Ensure 'UPnP Device Host (upnphost)' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\upnphost" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "346" + Task = "(HD) Ensure 'Link-Layer Topology Discovery Mapper (lltdsvc)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lltdsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "347" + Task = "(HD) Ensure 'Remote Access Auto Connection Manager (RasAuto)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasAuto" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "348" + Task = "(ND, NE) Ensure 'Web Management Service (WMSvc)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "349" + Task = "(ND, NE) Ensure 'Windows Media Player Network Sharing Service (WMPNetworkSvc)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMPNetworkSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "350" + Task = "(HD) Ensure 'Windows PushToInstall Service (PushToInstall)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PushToInstall" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "351" + Task = "(HD) Ensure 'Windows Mobile Hotspot Service (icssvc)' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\icssvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "352" + Task = "(HD) Ensure 'Windows Event Collector (Wecsvc)' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Wecsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "353" + Task = "(HD) Ensure 'Windows Error Reporting Service (WerSvc)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WerSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "354" + Task = "(HD) Ensure 'Windows Push Notifications System Service (WpnService)' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WpnService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "355" + Task = "(HD) Ensure 'Windows Remote Management (WS-Management) (WinRM)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinRM" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "356" + Task = "(ND, NE) Ensure 'World Wide Web Publishing Service (W3SVC)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "357" + Task = "(ND, NE) Ensure 'Xbox Accessory Management Service (XboxGipSvc)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxGipSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "358" + Task = "(ND, NE) Ensure 'Xbox Live Auth Manager (XblAuthManager)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblAuthManager" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "359" + Task = "(ND, NE) Ensure 'Xbox Live Networking Service (XboxNetApiSvc)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxNetApiSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "360" + Task = "(ND, NE) Ensure 'Xbox Live Game Save (XblGameSave)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblGameSave" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "361" + Task = "(ND) Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)'." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "362" + Task = "(ND) Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "363" + Task = "(ND) Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "364" + Task = "(ND) Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)'." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "365" + Task = "(ND, NE) Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)' ." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "366" + Task = "(ND, NE) Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "367" + Task = "(ND, NE) Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "368" + Task = "(ND, NE) Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "369" + Task = "(ND, NE) Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "370" + Task = "(ND, NE) Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "371" + Task = "(ND, NE) Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "372" + Task = "(ND, NE) Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "373" + Task = "(ND, NE) Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "374" + Task = "(ND, NE) Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#SecurityOptions.ps1 new file mode 100644 index 0000000..571931b --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#SecurityOptions.ps1 @@ -0,0 +1,156 @@ +[AuditTest] @{ + Id = "235" + Task = "(ND, NE) Configure 'Accounts: Rename administrator account'." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?!.*\bAdministrator\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "236" + Task = "(ND, NE) Ensure 'Accounts: Administrator account status' is set to 'Disabled'." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableAdminAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableAdminAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "237" + Task = "(ND, NE) Ensure 'Accounts: Guest account status' is set to 'Disabled'. " + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "238" + Task = "(ND, NE) Configure 'Accounts: Rename guest account'." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "249" + Task = "(ND) Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["ForceLogoffWhenHourExpire"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 1) { + return @{ + Message = "'ForceLogoffWhenHourExpire' currently set to: $setOption. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "263" + Task = "(ND) Ensure 'Network access: Allow anonymous SID/Name translation' is set to 'Disabled'." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} \ No newline at end of file diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#UserRights.ps1 new file mode 100644 index 0000000..2ffd579 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#UserRights.ps1 @@ -0,0 +1,1479 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + if ($sidAccount.Translate([System.Security.Principal.NTAccount]) -eq "NULL SID") { + return @{ + Account = $null + Sid = $sidAccount.Value + } + } else { + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "277" + Task = "(ND, NE) Ensure 'Change the system time' is set to 'Administrators, LOCAL SERVICE'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemtimePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemtimePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemtimePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "278" + Task = "(ND, NE) Ensure 'Change the time zone' is set to 'Administrators, LOCAL SERVICE, Users'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTimeZonePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTimeZonePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTimeZonePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "279" + Task = "(ND, NE) Ensure 'Increase scheduling priority' is set to 'Administrators, Window Manager\Window Manager Group'.`n`n" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseBasePriorityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-90-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseBasePriorityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseBasePriorityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "280" + Task = "(ND, NE) Ensure 'Deny log on as a batch job' to include 'ANONYMOUS LOGON, Guests'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyBatchLogonRight"] + $identityAccounts = @( + "S-1-5-7" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if($hyperVStatus -ne "Enabled"){ + [AuditTest] @{ + Id = "281" + Task = "(HD) Configure 'Log on as a service'. [Hyper-V-Feature NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeServiceLogonRight"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeServiceLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else{ + [AuditTest] @{ + Id = "281" + Task = "(HD) Configure 'Log on as a service'. [Hyper-V-Feature installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeServiceLogonRight"] + $identityAccounts = @( + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeServiceLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "282" + Task = "(ND, NE) Ensure 'Deny log on as a service' to include 'ANONYMOUS LOGON, Guests'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyServiceLogonRight"] + $identityAccounts = @( + "S-1-5-7" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "283" + Task = "(HD) Ensure 'Log on as a batch job' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBatchLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "284" + Task = "(ND) Ensure 'Deny log on through Remote Desktop Services' to include 'ANONYMOUS LOGON, Guests, Local account'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $missingUsers = @() + + #save all sids + foreach($sid in $currentUserRights.sid){ + $currentUserSIDs += $sid + } + #only these sids have to be in userRight + $identityAccounts = @( + "S-1-5-7" + "S-1-5-32-546" + "S-1-2-0" + ) + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "285" + Task = "(ND, NE) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators, Remote Desktop Users'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "286" + Task = "(ND, NE) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "287" + Task = "(ND, NE) Ensure 'Adjust memory quotas for a process' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE'.`n`n" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseQuotaPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseQuotaPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseQuotaPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "288" + Task = "(ND, NE) Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "289" + Task = "(ND, NE) Ensure 'Access this computer from the network' is set to 'Administrators, Remote Desktop Users'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "290" + Task = "(ND, NE) Ensure 'Debug programs' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "291" + Task = "(ND, NE) Ensure 'Perform volume maintenance tasks' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "292" + Task = "(ND, NE) Ensure 'Act as part of the operating system' is set to 'No One'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "293" + Task = "(ND) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'No One'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "294" + Task = "(ND, NE) Ensure 'Replace a process level token' is set to 'LOCAL SERVICE, NETWORK SERVICE'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAssignPrimaryTokenPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAssignPrimaryTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAssignPrimaryTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "295" + Task = "(ND, NE) Ensure 'Create a pagefile' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "296" + Task = "(ND, NE) Ensure 'Profile system performance' is set to 'Administrators, NT SERVICE\WdiServiceHost'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemProfilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemProfilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemProfilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "297" + Task = "(ND, NE) Ensure 'Profile single process' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "298" + Task = "(ND, NE) Ensure 'Create a token object' is set to 'No One'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "299" + Task = "(ND, NE) Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "300" + Task = "(ND, NE) Ensure 'Create symbolic links' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "301" + Task = "(ND, NE) Ensure 'Create permanent shared objects' is set to 'No One'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "302" + Task = "(ND, NE) Ensure 'Force shutdown from a remote system' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "303" + Task = "(ND, NE) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "304" + Task = "(ND, NE) Ensure 'Shut down the system' is set to 'Administrators, Users'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "305" + Task = "(ND, NE) Ensure 'Load and unload device drivers' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "306" + Task = "(ND, NE) Ensure 'Deny log on locally' to include 'ANONYMOUS LOGON, Guests'.`n" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-7" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "307" + Task = "(ND, NE) Ensure 'Allow log on locally' is set to 'Administrators, Users'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "308" + Task = "(ND, NE) Ensure 'Back up files and directories' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "309" + Task = "(ND, NE) Ensure 'Lock pages in memory' is set to 'No One'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "310" + Task = "(ND, NE) Ensure 'Take ownership of files or other objects' is set to 'Administrators' ." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "311" + Task = "(ND, NE) Ensure 'Modify firmware environment values' is set to 'Administrators'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "312" + Task = "(ND, NE) Ensure 'Modify an object label' is set to 'No One'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRelabelPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRelabelPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRelabelPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "313" + Task = "(ND, NE) Ensure 'Manage auditing and security log' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "314" + Task = "(ND, NE) Ensure 'Restore files and directories' is set to 'Administrators'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "315" + Task = "(ND, NE) Ensure 'Deny access to this computer from the network' to include 'ANONYMOUS LOGON, Guest, Local account'. `n`n" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-7" + "S-1-5-32-546" + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#AuditPolicies.ps1 new file mode 100644 index 0000000..b9e59ec --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#AuditPolicies.ps1 @@ -0,0 +1,1502 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "5.1.1.1" + Task = "Ensure 'Audit Credential Validation' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.1.1.2" + Task = "Ensure 'Audit User Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.1.1.3" + Task = "Ensure 'Audit Account Lockout' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.1.1.4" + Task = "Ensure 'Audit Group Membership' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.1.1.5" + Task = "Ensure 'Audit Logoff' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.1.1.6" + Task = "Ensure 'Audit Logon' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.1.1.7" + Task = "Ensure 'Audit Other Logon/Logoff Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.1.1.8" + Task = "Ensure 'Audit Special Logon' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.2.1.1" + Task = "Ensure 'Audit Other System Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.2.1.2" + Task = "Ensure 'Audit Security State Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.2.1.3" + Task = "Ensure 'Audit Security System Extension' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.2.1.4" + Task = "Ensure 'Audit System Integrity' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.2.1.5" + Task = "Ensure 'Audit File Share' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.2.1.6" + Task = "Ensure 'Audit Detailed File Share' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.2.1.7" + Task = "Ensure 'Audit Other Object Access Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.2.1.8" + Task = "Ensure 'Audit Removable Storage' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.2.1.9" + Task = "Ensure 'Audit PNP Activity' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.3.1.1" + Task = "Ensure 'Audit Security Group Management' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.3.1.2" + Task = "Ensure 'Audit Audit Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.3.1.3" + Task = "Ensure 'Audit Authentication Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.3.1.4" + Task = "Ensure 'Audit Authorization Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.3.1.5" + Task = "Ensure 'Audit MPSSVC Rule-Level Policy Change' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Mpssvc Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Mpssvc Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Mpssvc Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.3.1.6" + Task = "Ensure 'Audit Other Policy Change Events' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.5.1.1" + Task = "Ensure 'Audit Process Creation' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "5.5.1.2" + Task = "Ensure 'Audit Sensitive Privilege Use' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#RegistrySettings.ps1 new file mode 100644 index 0000000..797ad37 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#RegistrySettings.ps1 @@ -0,0 +1,711 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "4.1.1" + Task = "Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "CrashOnAuditFail" ` + | Select-Object -ExpandProperty "CrashOnAuditFail" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.1.2" + Task = "Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.2.1.1" + Task = "Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\domainfw.log'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SYSTEMROOT%\System32\logfiles\firewall\domainfw.log"; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "4.2.1.2" + Task = "Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "4.2.1.3" + Task = "Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "4.2.1.4" + Task = "Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "4.2.2.1" + Task = "Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\privatefw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PrivateProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\privatefw.log"; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "4.2.2.2" + Task = "Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "4.2.2.3" + Task = "Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "4.2.2.4" + Task = "Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "4.2.3.1" + Task = "Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "4.2.3.2" + Task = "Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "4.2.3.3" + Task = "Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\publicfw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\publicfw.log"; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "4.2.3.4" + Task = "Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "4.3.1.1" + Task = "Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security" ` + -Name "WarningLevel" ` + | Select-Object -ExpandProperty "WarningLevel" + + if (($regValue -gt 90)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 90" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.3.2.1.1" + Task = "Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.3.2.1.2" + Task = "Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.3.2.2.1" + Task = "Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.3.2.2.2" + Task = "Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.3.2.3.1" + Task = "Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 196608)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.3.2.3.2" + Task = "Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.3.2.4.1" + Task = "Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.3.2.4.2" + Task = "Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.3.3.1" + Task = "Ensure 'Include command line in process creation events' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.3.4.2" + Task = "Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.3.4.3" + Task = "Ensure 'Turn on PowerShell Transcription' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" ` + -Name "EnableTranscripting" ` + | Select-Object -ExpandProperty "EnableTranscripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#AccountPolicies.ps1 new file mode 100644 index 0000000..b170726 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#AccountPolicies.ps1 @@ -0,0 +1,171 @@ +[AuditTest] @{ + Id = "200" + Task = "(ND, NE) Ensure 'Store passwords using reversible encryption' is set to 'Disabled'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "201" + Task = "(ND, NE) Ensure 'Password must meet complexity requirements' is set to 'Enabled'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "202" + Task = "(ND, NE) Ensure 'Enforce password history' is set to '24 or more password(s)'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "203" + Task = "(ND, NE) Ensure 'Maximum password age' is set to '365 or fewer days, but not 0'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 365 -or $setPolicy -le 0)) { + if($setPolicy -eq -1){ #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 365 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "204" + Task = "(ND, NE) Ensure 'Minimum password length' is set to '14 or more character(s)'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "205" + Task = "(ND, NE) Ensure 'Minimum password age' is set to '1 or more day(s)' ." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 1)) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#AuditPolicies.ps1 new file mode 100644 index 0000000..346e5c7 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#AuditPolicies.ps1 @@ -0,0 +1,77 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#RegistrySettings.ps1 new file mode 100644 index 0000000..e1bbaea --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#RegistrySettings.ps1 @@ -0,0 +1,8320 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$avstatus = CheckForActiveAV +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "1" + Task = "(ND, NE) Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2" + Task = "(ND, NE) Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3" + Task = "(ND, NE) Ensure 'Configure SMB v1 server' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4" + Task = "(ND, NE) Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5" + Task = "(ND, NE) Ensure 'WDigest Authentication' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "6" + Task = "(ND, NE) Ensure 'LSA Protection' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RunAsPPL" ` + | Select-Object -ExpandProperty "RunAsPPL" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "7" + Task = "(ND, NE) Ensure 'MSS: (EnableDeadGWDetect) Allow automatic detection of dead network gateways (could lead to DoS)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableDeadGWDetect" ` + | Select-Object -ExpandProperty "EnableDeadGWDetect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "8" + Task = "(ND, NE) Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon(not recommended)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9" + Task = "(ND, NE) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "10" + Task = "(ND, NE) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "12" + Task = "(ND, NE) Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "14" + Task = "(ND, NE) Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "16" + Task = "(ND, NE) Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "17" + Task = "(ND, NE) Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScreenSaverGracePeriod" ` + | Select-Object -ExpandProperty "ScreenSaverGracePeriod" + + if ($regValue -notmatch "^[0-5]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[0-5]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "20" + Task = "(ND, NE) Ensure 'Turn off multicast name resolution' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "21" + Task = "(ND, NE) Ensure 'NetBIOS node type' is set to 'P-node'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "22" + Task = "(ND, NE) Ensure 'Enable insecure guest logons' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24 A" + Task = "(ND, NE) Ensure 'Hardened UNC Paths' is set to `"Require Mutual Authentication=1, `"Require Integrity=1`" for the value names `"\\*\NETLOGON`" und `"\\*\SYSVOL`". [\\*\NETLOGON]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if ($regValue -eq $null) { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object { $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "24 B" + Task = "(ND, NE) Ensure 'Hardened UNC Paths' is set to `"Require Mutual Authentication=1, `"Require Integrity=1`" for the value names `"\\*\NETLOGON`" und `"\\*\SYSVOL`". [\\*\SYSVOL]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if ($regValue -eq $null) { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object { $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "33" + Task = "(ND, NE) Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to the value 'Enabled: 1 = Minimize the number of simultaneous connections'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fMinimizeConnections" ` + | Select-Object -ExpandProperty "fMinimizeConnections" + + if ($null -eq $regValue -or 0 -eq $regValue) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1-3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "34" + Task = "(ND) Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($regValue -eq 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "35" + Task = "(ND, NE) Ensure 'Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config" ` + -Name "AutoConnectAllowedOEM" ` + | Select-Object -ExpandProperty "AutoConnectAllowedOEM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "37" + Task = "(ND, NE) Ensure 'Turn off toast notifications on the lock screen' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "39" + Task = "(ND, NE) Ensure 'Turn off picture password sign-in' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "BlockDomainPicturePassword" ` + | Select-Object -ExpandProperty "BlockDomainPicturePassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "40" + Task = "(ND, NE) Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "41" + Task = "(ND, NE) Ensure 'Block user from showing account details on signin' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockUserFromShowingAccountDetailsOnSignin" ` + | Select-Object -ExpandProperty "BlockUserFromShowingAccountDetailsOnSignin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "44" + Task = "(ND, NE) Ensure 'Do not display network selection UI' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "46" + Task = "(ND, NE) Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "50" + Task = "(ND, NE) Ensure 'Encryption Oracle Remediation' is set to 'Enabled: Force Updated Clients'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "52" + Task = "(ND, NE) Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled' ." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "53" + Task = "(ND, NE) Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "54" + Task = "(ND, NE) Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "55" + Task = "(ND, NE) Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "56" + Task = "(ND, NE) Ensure 'Allow standby states (S1-S3) when sleeping (on battery)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "57" + Task = "(ND, NE) Ensure 'Allow standby states (S1-S3) when sleeping (plugged in)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "59 A" + Task = "(ND, NE) Ensure 'Prevent installation of devices that match any of these device IDs' is configured." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceIDs" ` + | Select-Object -ExpandProperty "DenyDeviceIDs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "59 B" + Task = "(ND, NE) Ensure 'Prevent installation of devices that match any of these device IDs' is configured. (PCI\CC_0C0A)" + Test = { + try { + $valueNames = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceIDs" + + $expectedValue = "PCI\CC_0C0A" + + foreach ($obj in $valueNames.PSObject.Properties) { + if ($obj.Value -eq $expectedValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Registry value is missing: $expectedValue" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "59 C" + Task = "(ND, NE) Ensure 'Prevent installation of devices that match any of these device IDs' is configured. (DenyDeviceIDsRetroactive)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceIDsRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceIDsRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "60 A" + Task = "(ND, NE) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClasses" ` + | Select-Object -ExpandProperty "DenyDeviceClasses" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "60 B" + Task = "(ND, NE) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured. (Blocking the SBP-2 driver and Thunderbolt controllers to reduce 1394 DMA and Thunderbolt DMA threats to BitLocker)" + Test = { + try { + $valueNames = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" + + $expectedValue = "{d48179be-ec20-11d1-b6b8-00c04fa372a7}" + + foreach ($obj in $valueNames.PSObject.Properties) { + if ($obj.Value -eq $expectedValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Registry value is missing: $expectedValue" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "60 C" + Task = "(ND, NE) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured. (IEEE 1394 Devices That Support the 61883 Protocol)" + Test = { + try { + $valueNames = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" + + $expectedValue = "{7ebefbc0-3200-11d2-b4c2-00a0C9697d07}" + + foreach ($obj in $valueNames.PSObject.Properties) { + if ($obj.Value -eq $expectedValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Registry value is missing: $expectedValue" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "60 D" + Task = "(ND, NE) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured. (IEEE 1394 Devices That Support the AVC Protocol)" + Test = { + try { + $valueNames = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" + + $expectedValue = "{c06ff265-ae09-48f0-812c-16753d7cba83}" + + foreach ($obj in $valueNames.PSObject.Properties) { + if ($obj.Value -eq $expectedValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Registry value is missing: $expectedValue" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "60 E" + Task = "(ND, NE) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured. (IEEE 1394 Host Bus Controller)" + Test = { + try { + $valueNames = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" + + $expectedValue = "{6bdd1fc1-810f-11d0-bec7-08002be2092f}" + + foreach ($obj in $valueNames.PSObject.Properties) { + if ($obj.Value -eq $expectedValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Registry value is missing: $expectedValue" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "60 F" + Task = "(ND, NE) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured. (DenyDeviceClassesRetroactive)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClassesRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceClassesRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "61" + Task = "(ND, NE) Ensure 'Continue experiences on this device' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableCdp" ` + | Select-Object -ExpandProperty "EnableCdp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "68" + Task = "(ND, NE) Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "74" + Task = "(ND, NE) Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "81" + Task = "(ND, NE) Ensure 'Enumeration policy for external devices incompatible with Kernel DMA Protection' is set to 'Enabled: Block All'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "84" + Task = "(ND, NE) Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' ." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "85" + Task = "(ND, NE) Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "EnableAuthEpResolution" ` + | Select-Object -ExpandProperty "EnableAuthEpResolution" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "86" + Task = "(ND, NE) Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "87" + Task = "(ND, NE) Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "88" + Task = "(ND, NE) Ensure 'Ignore the default list of blocked TPM commands' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\TPM\BlockedCommands" ` + -Name "IgnoreDefaultList" ` + | Select-Object -ExpandProperty "IgnoreDefaultList" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "89" + Task = "(ND, NE) Ensure 'Standard User Lockout Duration' is set to '30 minutes'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Tpm" ` + -Name "StandardUserAuthorizationFailureDuration" ` + | Select-Object -ExpandProperty "StandardUserAuthorizationFailureDuration" + + if ($regValue -ne 30) { + return @{ + Message = "Registry value is '$regValue'. Expected: 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "90" + Task = "(ND, NE) Ensure 'Standard User Total Lockout Threshold' is set to '5'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Tpm" ` + -Name "StandardUserAuthorizationFailureIndividualThreshold" ` + | Select-Object -ExpandProperty "StandardUserAuthorizationFailureIndividualThreshold" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "94" + Task = "(ND, NE) Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "95" + Task = "(ND, NE) Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "96" + Task = "(ND, NE) Ensure 'Force specific screen saver: Screen saver executable name' is set to 'Enabled: scrnsave.scr'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "SCRNSAVE.EXE" ` + | Select-Object -ExpandProperty "SCRNSAVE.EXE" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "97" + Task = "(ND, NE) Ensure 'Enable screen saver' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaveActive" ` + | Select-Object -ExpandProperty "ScreenSaveActive" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "98" + Task = "(ND, NE) Ensure 'Password protect the screen saver' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaverIsSecure" ` + | Select-Object -ExpandProperty "ScreenSaverIsSecure" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "99" + Task = "(ND, NE) Ensure 'Screen saver timeout' is set to 'Enabled: 900 seconds or fewer, but not 0'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaveTimeOut" ` + | Select-Object -ExpandProperty "ScreenSaveTimeOut" + + if (($regValue -gt 900 -or $regValue -le 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x > 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "100 A" + Task = "(ND, NE) Ensure 'Turn off automatic learning' is set to 'Enabled' for ImplicitTextCollection." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "RestrictImplicitTextCollection" ` + | Select-Object -ExpandProperty "RestrictImplicitTextCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "100 B" + Task = "(ND, NE) Ensure 'Turn off automatic learning' is set to 'Enabled' for ImplicitInkCollection." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "RestrictImplicitInkCollection" ` + | Select-Object -ExpandProperty "RestrictImplicitInkCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "101" + Task = "(ND, NE) Ensure 'Allow users to enable online speech recognition services' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "AllowInputPersonalization" ` + | Select-Object -ExpandProperty "AllowInputPersonalization" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "102" + Task = "(ND, NE) Ensure 'Notify antivirus programs when opening attachments' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "ScanWithAntiVirus" ` + | Select-Object -ExpandProperty "ScanWithAntiVirus" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "103" + Task = "(ND, NE) Ensure 'Do not preserve zone information in file attachments' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "106" + Task = "(ND, NE) Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "107" + Task = "(ND, NE) Ensure 'Do not display the password reveal button' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "109" + Task = "(ND, NE) Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "112" + Task = "(ND, NE) Ensure 'Do not suggest third-party content in Windows spotlight' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "113" + Task = "(ND, NE) Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "114" + Task = "(ND, NE) Ensure 'Configure Windows spotlight on lock screen' is set to Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "ConfigureWindowsSpotlight" ` + | Select-Object -ExpandProperty "ConfigureWindowsSpotlight" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "115" + Task = "(ND, NE) Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "116" + Task = "(ND, NE) Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "117" + Task = "(ND, NE) Ensure 'Turn off heap termination on corruption' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "118" + Task = "(ND, NE) Ensure 'Toggle user control over Insider builds' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" ` + -Name "AllowBuildPreview" ` + | Select-Object -ExpandProperty "AllowBuildPreview" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "119" + Task = "(ND, NE) Ensure 'Do not show feedback notifications' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DoNotShowFeedbackNotifications" ` + | Select-Object -ExpandProperty "DoNotShowFeedbackNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "120" + Task = "(ND, NE) Ensure 'Allow Telemetry' is set to 'Enabled: 0 - Security [Enterprise Only] or Enabled: 1 - Basic'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + $saferClients = @("*Server*", "*Education*", "*Enterprise*") + $productname = Get-ComputerInfo | select -ExpandProperty OsName + if (($productname -notcontains $saferClients) -and ($regValue -eq 1)) { + return @{ + Message = "Registry value is '$regValue'. Your OS $productname does not support 'Diagnostic data off'." + Status = "Warning" + } + } + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "121" + Task = "(ND, NE) Ensure 'Allow device name to be sent in Windows diagnostic data' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowDeviceNameInTelemetry" ` + | Select-Object -ExpandProperty "AllowDeviceNameInTelemetry" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "124" + Task = "(ND, NE) Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount" ` + -Name "DisableUserAuth" ` + | Select-Object -ExpandProperty "DisableUserAuth" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "126" + Task = "(ND, NE) Ensure 'Prevent users from sharing files within their profile.' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInplaceSharing" ` + | Select-Object -ExpandProperty "NoInplaceSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "127" + Task = "(ND, NE) Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "131" + Task = "(ND, NE) Ensure 'Do not allow drive redirection' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "134" + Task = "(ND, NE) Ensure 'Always prompt for password upon connection' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "135" + Task = "(ND, NE) Ensure 'Require user authentication for remote connections by using Network Level Authentication' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "UserAuthentication" ` + | Select-Object -ExpandProperty "UserAuthentication" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "136" + Task = "(ND, NE) Ensure 'Require secure RPC communication' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "137" + Task = "(ND, NE) Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "138" + Task = "(ND, NE) Ensure 'Require use of specific security layer for remote (RDP) connections' is set to 'Enabled: SSL'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SecurityLayer" ` + | Select-Object -ExpandProperty "SecurityLayer" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "139" + Task = "(ND, NE) Ensure 'End session when time limits are reached' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fResetBroken" ` + | Select-Object -ExpandProperty "fResetBroken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "142" + Task = "(ND, NE) Ensure 'Do not use temporary folders per session' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "PerSessionTempDir" ` + | Select-Object -ExpandProperty "PerSessionTempDir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "143" + Task = "(ND, NE) Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "145" + Task = "(ND, NE) Ensure 'Do not allow passwords to be saved' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "146" + Task = "(ND, NE) Ensure 'Disallow Autoplay for non-volume devices' is set to'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "147" + Task = "(ND, NE) Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "148" + Task = "(ND, NE) Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "149" + Task = "(ND, NE) Ensure 'Prevent downloading of enclosures' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "152" + Task = "(ND, NE) Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "AutoDownload" ` + | Select-Object -ExpandProperty "AutoDownload" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "153" + Task = "(ND, NE) Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "DisableOSUpgrade" ` + | Select-Object -ExpandProperty "DisableOSUpgrade" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "157" + Task = "(ND, NE) Ensure 'Allow search and Cortana to use location' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowSearchToUseLocation" ` + | Select-Object -ExpandProperty "AllowSearchToUseLocation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "158" + Task = "(ND, NE) Ensure 'Allow indexing of encrypted files' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "159" + Task = "(ND, NE) Ensure 'Improve inking and typing recognition' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\TextInput" ` + -Name "AllowLinguisticDataCollection" ` + | Select-Object -ExpandProperty "AllowLinguisticDataCollection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "160" + Task = "(ND, NE) Ensure 'Download Mode' is set to 'Enabled: Simple (99)' ." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization" ` + -Name "DODownloadMode" ` + | Select-Object -ExpandProperty "DODownloadMode" + + if ($regValue -ne 99) { + return @{ + Message = "Registry value is '$regValue'. Expected: 99" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "161" + Task = "(ND, NE) Ensure 'Require pin for pairing' is set to 'Enabled: Always'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect" ` + -Name "RequirePinForPairing" ` + | Select-Object -ExpandProperty "RequirePinForPairing" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "162" + Task = "(ND, NE) Ensure 'Configure detection for potentially unwanted applications' is set to 'Enabled: Block'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "163" + Task = "(ND, NE) Ensure 'Turn off Windows Defender Antivirus' is set to 'Disabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender" ` + -Name "DisableAntiSpyware" ` + | Select-Object -ExpandProperty "DisableAntiSpyware" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "164" + Task = "(ND, NE) Ensure 'Configure Watson events' is set to 'Disabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Reporting" ` + -Name "DisableGenericReports" ` + | Select-Object -ExpandProperty "DisableGenericReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "165" + Task = "(ND, NE) Ensure 'Turn on behavior monitoring' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "167" + Task = "(ND, NE) Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "168" + Task = "(ND, NE) Ensure 'Turn on e-mail scanning' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "169" + Task = "(ND, NE) Ensure 'Scan removable drives' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "170" + Task = "(ND, NE) Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "171" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 A" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office communication application from creating child processes)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 B" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from creating executable content)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 C" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block execution of potentially obfuscated scripts)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 D" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from injecting code into other processes)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 E" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Adobe Reader from creating child processes)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 F" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Win32 API calls from Office macro)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 G" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block credential stealing from the Windows local security authority subsystem (lsass.exe))" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 H" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block untrusted and unsigned processes that run from USB)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 I" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block executable content from email client and webmail)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 J" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block JavaScript or VBScript from launching downloaded executable content)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "172 K" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from creating child processes)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "173" + Task = "(ND, NE) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "174" + Task = "(ND, NE) Ensure 'Prevent bypassing Windows Defender SmartScreen prompts for sites' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "175" + Task = "(ND, NE) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "177" + Task = "(ND, NE) Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if (($regValue -ne 1) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "178" + Task = "(ND, NE) Ensure 'Allow user control over installs' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "180" + Task = "(ND, NE) Ensure 'Always install with elevated privileges' is set to 'Disabled' on local_machine." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "181" + Task = "(ND, NE) Ensure 'Always install with elevated privileges' is set to 'Disabled' on current_user." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "183" + Task = "(ND, NE) Ensure 'Turn on Script Execution' is set to 'Enabled: Allow local scripts and remote signed scripts'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\PowerShell" ` + -Name "ExecutionPolicy" ` + | Select-Object -ExpandProperty "ExecutionPolicy" + + if ($regValue -ne "RemoteSigned") { + return @{ + Message = "Registry value is '$regValue'. Expected: RemoteSigned" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "185" + Task = "(ND, NE) Ensure 'Configure Automatic Updates' is set to 'Enabled: 4 Auto download and schedule the install'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "186" + Task = "(ND, NE) Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "187" + Task = "(ND, NE) Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "188" + Task = "(ND, NE) Ensure 'Remove access to `"Pause updates`" feature' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "SetDisablePauseUXAccess" ` + | Select-Object -ExpandProperty "SetDisablePauseUXAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "189" + Task = "(ND, NE) Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "191" + Task = "(ND, NE) Ensure 'Allow Basic authentication' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "192" + Task = "(ND, NE) Ensure 'Disallow Digest authentication' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "193" + Task = "(ND, NE) Ensure 'Allow unencrypted traffic' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "194" + Task = "(ND, NE) Ensure 'Allow Basic authentication' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "196" + Task = "(ND, NE) Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "197" + Task = "(ND, NE) Ensure 'Allow unencrypted traffic' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "198" + Task = "(ND, NE) Ensure 'Prevent users from modifying settings' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender Security Center\App and Browser protection" ` + -Name "DisallowExploitProtectionOverride" ` + | Select-Object -ExpandProperty "DisallowExploitProtectionOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "199" + Task = "(ND, NE) Ensure 'Enables or disables Windows Game Recording and Broadcasting' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR" ` + -Name "AllowGameDVR" ` + | Select-Object -ExpandProperty "AllowGameDVR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "209" + Task = "(ND, NE) Configure 'Interactive logon: Message title for users attempting to log on'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "210" + Task = "(ND, NE) Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "211" + Task = "(ND, NE) Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "212" + Task = "(ND, NE) Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "213" + Task = "(ND, NE) Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "214" + Task = "(ND, NE) Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "215" + Task = "(ND, NE) Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "216" + Task = "(ND, NE) Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableUIADesktopToggle" ` + | Select-Object -ExpandProperty "EnableUIADesktopToggle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "217" + Task = "(ND, NE) Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "218" + Task = "(ND, NE) Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Prompt for credentials on the secure desktop'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "226" + Task = "(ND, NE) Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators and Interactive Users'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AllocateDASD" ` + | Select-Object -ExpandProperty "AllocateDASD" + + if ($regValue -ne "2") { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "227" + Task = "(ND, NE) Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if (($regValue -gt 14 -or $regValue -lt 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 14 and x >= 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "229" + Task = " Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "230" + Task = "(ND, NE) Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "231" + Task = "(ND, NE) Configure 'Interactive logon: Message text for users attempting to log on'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "234" + Task = "(ND, NE) Ensure 'Interactive logon: Don't display last signed-in' is setto 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "239" + Task = "(ND, NE) Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "240" + Task = "(ND, NE) Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "NoConnectedUser" ` + | Select-Object -ExpandProperty "NoConnectedUser" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "241" + Task = "(ND, NE) Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'." + Test = { + try { + if ((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "242" + Task = "(ND, NE) Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'." + Test = { + try { + if ((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True) { + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "243" + Task = "(ND, NE) Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "244" + Task = "(ND, NE) Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "enableforcedlogoff" ` + | Select-Object -ExpandProperty "enableforcedlogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "245" + Task = "(ND, NE) Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'." + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "246" + Task = "(ND, NE) Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'. " + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True) { + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "247" + Task = "(ND, NE) Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s)'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if (($regValue -gt 15)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "252" + Task = "(ND) Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "253" + Task = "(ND, NE) Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "254" + Task = "(ND, NE) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "255" + Task = "(ND, NE) Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "256" + Task = "(ND, NE) Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "257" + Task = "(ND) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "258" + Task = "(ND) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "259" + Task = "(ND) Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if (($regValue -lt 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "260" + Task = "(ND, NE) Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "261" + Task = "(ND, NE) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "262" + Task = "(ND) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "264" + Task = "(ND, NE) Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "265" + Task = "(ND, NE) Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "restrictremotesam" ` + | Select-Object -ExpandProperty "restrictremotesam" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "266" + Task = "(ND) Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "267" + Task = "(ND, NE) Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionShares" ` + | Select-Object -ExpandProperty "NullSessionShares" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "268" + Task = "(ND, NE) Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "269" + Task = "(ND, NE) Ensure 'Network access: Named Pipes that can be accessed anonymously' is set to 'None'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "270" + Task = "(ND, NE) Configure 'Network access: Remotely accessible registry paths and sub-paths'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "271" + Task = "(ND, NE) Configure 'Network access: Remotely accessible registry paths'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\ProductOptions" + "System\CurrentControlSet\Control\Server Applications" + "Software\Microsoft\Windows NT\CurrentVersion" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\ProductOptions System\CurrentControlSet\Control\Server Applications Software\Microsoft\Windows NT\CurrentVersion" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "272" + Task = "(ND, NE) Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "275" + Task = "(ND, NE) Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "276" + Task = "(ND, NE) Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "317" + Task = "(ND, NE) Ensure 'Connected User Experiences and Telemetry' is set to 'Disabled'." + Test = { + try { + $status = Get-Service DiagTrack -ErrorAction Stop | select -property starttype + if ($status.StartType -ne "Disabled") { + return @{ + Message = "Service not compliant. Currently: $($status)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + catch [System.SystemException] { + return @{ + Message = "Service not found!" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "320" + Task = "(ND, NE) Ensure 'Computer Browser (Browser)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "321" + Task = "(NE, ND) Ensure 'Internet Connection Sharing (ICS) (SharedAccess)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "323" + Task = "(ND, NE) Ensure 'IIS Admin Service (IISADMIN)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IISADMIN" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "324" + Task = "(NE, ND) Ensure 'Infrared monitor service (irmon)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\irmon" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "326" + Task = "(ND, NE) Ensure 'LxssManager (LxssManager)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $result = Get-WindowsOptionalFeature -online -FeatureName Microsoft-Windows-Subsystem-Linux + $state = $result.State + if ($state -eq "Disabled" -or $state -eq "Not Installed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + else { + return @{ + Message = "Registry value is '$state'. Expected: 'Disabled' or 'Not Installed'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Value not found." + Status = "Error" + } + } + } +} +[AuditTest] @{ + Id = "328" + Task = "(ND, NE) Ensure 'Microsoft FTP Service (FTPSVC)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FTPSVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "331" + Task = "(ND, NE) Ensure 'OpenSSH SSH Server (sshd)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sshd" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "338" + Task = "(ND, NE) Ensure 'Routing and Remote Access (RemoteAccess)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "339" + Task = "(ND, NE) Ensure 'Remote Procedure Call (RPC) Locator (RpcLocator)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcLocator" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "341" + Task = "(ND, NE) Ensure 'Simple TCP/IP Services (simptcp)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\simptcp" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "343" + Task = "(ND, NE) Ensure 'SSDP Discovery (SSDPSRV)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SSDPSRV" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "345" + Task = "(ND, NE) Ensure 'UPnP Device Host (upnphost)' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\upnphost" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "348" + Task = "(ND, NE) Ensure 'Web Management Service (WMSvc)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "349" + Task = "(ND, NE) Ensure 'Windows Media Player Network Sharing Service (WMPNetworkSvc)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMPNetworkSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "351" + Task = "(HD) Ensure 'Windows Mobile Hotspot Service (icssvc)' is set to 'Disabled'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\icssvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "356" + Task = "(ND, NE) Ensure 'World Wide Web Publishing Service (W3SVC)' is set to 'Disabled' or 'Not Installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "357" + Task = "(ND, NE) Ensure 'Xbox Accessory Management Service (XboxGipSvc)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxGipSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "358" + Task = "(ND, NE) Ensure 'Xbox Live Auth Manager (XblAuthManager)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblAuthManager" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "359" + Task = "(ND, NE) Ensure 'Xbox Live Networking Service (XboxNetApiSvc)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxNetApiSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "360" + Task = "(ND, NE) Ensure 'Xbox Live Game Save (XblGameSave)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblGameSave" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "365" + Task = "(ND, NE) Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)' ." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "366" + Task = "(ND, NE) Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "367" + Task = "(ND, NE) Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "368" + Task = "(ND, NE) Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "369" + Task = "(ND, NE) Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "370" + Task = "(ND, NE) Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "371" + Task = "(ND, NE) Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "372" + Task = "(ND, NE) Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "373" + Task = "(ND, NE) Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "374" + Task = "(ND, NE) Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#SecurityOptions.ps1 new file mode 100644 index 0000000..0f51558 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#SecurityOptions.ps1 @@ -0,0 +1,130 @@ +[AuditTest] @{ + Id = "235" + Task = "(ND, NE) Configure 'Accounts: Rename administrator account'." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?!.*\bAdministrator\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "236" + Task = "(ND, NE) Ensure 'Accounts: Administrator account status' is set to 'Disabled'." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableAdminAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableAdminAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "237" + Task = "(ND, NE) Ensure 'Accounts: Guest account status' is set to 'Disabled'. " + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "238" + Task = "(ND, NE) Configure 'Accounts: Rename guest account'." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "263" + Task = "(ND) Ensure 'Network access: Allow anonymous SID/Name translation' is set to 'Disabled'." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} \ No newline at end of file diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#UserRights.ps1 new file mode 100644 index 0000000..b0a00fd --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#UserRights.ps1 @@ -0,0 +1,1385 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + if ($sidAccount.Translate([System.Security.Principal.NTAccount]) -eq "NULL SID") { + return @{ + Account = $null + Sid = $sidAccount.Value + } + } else { + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "277" + Task = "(ND, NE) Ensure 'Change the system time' is set to 'Administrators, LOCAL SERVICE'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemtimePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemtimePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemtimePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "278" + Task = "(ND, NE) Ensure 'Change the time zone' is set to 'Administrators, LOCAL SERVICE, Users'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTimeZonePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTimeZonePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTimeZonePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "279" + Task = "(ND, NE) Ensure 'Increase scheduling priority' is set to 'Administrators, Window Manager\Window Manager Group'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseBasePriorityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-90-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseBasePriorityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseBasePriorityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "280" + Task = "(ND, NE) Ensure 'Deny log on as a batch job' to include 'ANONYMOUS LOGON, Guests'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyBatchLogonRight"] + $identityAccounts = @( + "S-1-5-7" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "282" + Task = "(ND, NE) Ensure 'Deny log on as a service' to include 'ANONYMOUS LOGON, Guests'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyServiceLogonRight"] + $identityAccounts = @( + "S-1-5-7" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "284" + Task = "(ND) Ensure 'Deny log on through Remote Desktop Services' to include 'ANONYMOUS LOGON, Guests, Local account'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $missingUsers = @() + + #save all sids + foreach($sid in $currentUserRights.sid){ + $currentUserSIDs += $sid + } + #only these sids have to be in userRight + $identityAccounts = @( + "S-1-5-7" + "S-1-5-32-546" + "S-1-2-0" + ) + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "285" + Task = "(ND, NE) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators, Remote Desktop Users'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "286" + Task = "(ND, NE) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "287" + Task = "(ND, NE) Ensure 'Adjust memory quotas for a process' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseQuotaPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseQuotaPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseQuotaPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "288" + Task = "(ND, NE) Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "289" + Task = "(ND, NE) Ensure 'Access this computer from the network' is set to 'Administrators, Remote Desktop Users'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "290" + Task = "(ND, NE) Ensure 'Debug programs' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "291" + Task = "(ND, NE) Ensure 'Perform volume maintenance tasks' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "292" + Task = "(ND, NE) Ensure 'Act as part of the operating system' is set to 'No One'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "294" + Task = "(ND, NE) Ensure 'Replace a process level token' is set to 'LOCAL SERVICE, NETWORK SERVICE'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAssignPrimaryTokenPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAssignPrimaryTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAssignPrimaryTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "295" + Task = "(ND, NE) Ensure 'Create a pagefile' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "296" + Task = "(ND, NE) Ensure 'Profile system performance' is set to 'Administrators, NT SERVICE\WdiServiceHost'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemProfilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemProfilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemProfilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "297" + Task = "(ND, NE) Ensure 'Profile single process' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "298" + Task = "(ND, NE) Ensure 'Create a token object' is set to 'No One'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "299" + Task = "(ND, NE) Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if($hyperVStatus -ne "Enabled"){ + [AuditTest] @{ + Id = "300" + Task = "(ND, NE) Ensure 'Create symbolic links' is set to 'Administrators'. [Hyper-V-Feature NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else{ + [AuditTest] @{ + Id = "300" + Task = "(ND, NE) Ensure 'Create symbolic links' is set to 'Administrators, NT Virtual Machine'. [Hyper-V-Feature installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "301" + Task = "(ND, NE) Ensure 'Create permanent shared objects' is set to 'No One'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "302" + Task = "(ND, NE) Ensure 'Force shutdown from a remote system' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "303" + Task = "(ND, NE) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "304" + Task = "(ND, NE) Ensure 'Shut down the system' is set to 'Administrators, Users'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "305" + Task = "(ND, NE) Ensure 'Load and unload device drivers' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "306" + Task = "(ND, NE) Ensure 'Deny log on locally' to include 'ANONYMOUS LOGON, Guests'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-7" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "307" + Task = "(ND, NE) Ensure 'Allow log on locally' is set to 'Administrators, Users'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "308" + Task = "(ND, NE) Ensure 'Back up files and directories' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "309" + Task = "(ND, NE) Ensure 'Lock pages in memory' is set to 'No One'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "310" + Task = "(ND, NE) Ensure 'Take ownership of files or other objects' is set to 'Administrators' ." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "311" + Task = "(ND, NE) Ensure 'Modify firmware environment values' is set to 'Administrators'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "312" + Task = "(ND, NE) Ensure 'Modify an object label' is set to 'No One'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRelabelPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRelabelPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRelabelPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "313" + Task = "(ND, NE) Ensure 'Manage auditing and security log' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "314" + Task = "(ND, NE) Ensure 'Restore files and directories' is set to 'Administrators'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "315" + Task = "(ND, NE) Ensure 'Deny access to this computer from the network' to include 'ANONYMOUS LOGON, Guest, Local account'. " + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-7" + "S-1-5-32-546" + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHus-Telemetrie-BSI-V1.2#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHus-Telemetrie-BSI-V1.2#RegistrySettings.ps1 new file mode 100644 index 0000000..85c7f0d --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10 SiSyPHus-Telemetrie-BSI-V1.2#RegistrySettings.ps1 @@ -0,0 +1,289 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$avstatus = CheckForActiveAV +$windefrunning = CheckWindefRunning +if((Get-WmiObject -class Win32_OperatingSystem).Caption -eq "Microsoft Windows 10 Enterprise Evaluation" -or +(Get-WmiObject -class Win32_OperatingSystem).Caption -eq "Microsoft Windows 10 Enterprise"){ + [AuditTest] @{ + Id = "3.1.1" + Task = "Configuration of the lowest possible telemetry-level (Enterprise Windows 10)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +else{ + [AuditTest] @{ + Id = "3.1.1" + Task = "Configuration of the lowest possible telemetry-level (Non-Enterprise Windows 10)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + $saferClients = @("*Server*","*Education*","*Enterprise*") + $productname = Get-ComputerInfo | select -ExpandProperty OsName + if (($productname -notcontains $saferClients) -and ($regValue -eq 1)){ + return @{ + Message = "Registry value is '$regValue'. Your OS $productname does not support 'Diagnostic data off'." + Status = "Warning" + } + } + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "3.1.2 A" + Task = "Deactivation of the telemetry service and ETW-sessions - disable service DiagTrack" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DiagTrack" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.1.2 B" + Task = "Deactivation of the telemetry service and ETW-sessions - disable service Autologger-Diagtrack-Listener" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WMI\Autologger\AutoLogger-Diagtrack-Listener" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.1.3 A" + Task = "Deactivation of telemetry according to Microsoft - Disable Windows Update Service" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wuauserv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.1.3 B" + Task = "Deactivation of telemetry according to Microsoft - Cloud-Based-Protection: disable MAPS" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.1.3 C" + Task = "Deactivation of telemetry according to Microsoft - Cloud-Based-Protection: never send sample files" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SubmitSamplesConsent" ` + | Select-Object -ExpandProperty "SubmitSamplesConsent" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#AccountPolicies.ps1 new file mode 100644 index 0000000..3819cd2 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#AccountPolicies.ps1 @@ -0,0 +1,199 @@ +[AuditTest] @{ + Id = "Medium-001" + Task = "Ensure 'Account lockout duration' is set to 0" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -ne 0)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x == 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-002" + Task = "Ensure 'Account lockout threshold' is set to '5 or fewer invalid logon attempt(s), but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 5 -or $setPolicy -le 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 5 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-003" + Task = " Ensure 'Reset account lockout counter after' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -ne 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x == 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-146" + Task = "Ensure 'Maximum password age' is set to '365 or fewer days, but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 365 -or $setPolicy -le 0)) { + if($setPolicy -eq -1){ #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 365 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-147" + Task = "Ensure 'Minimum password length' is set to '14 or more character(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-148" + Task = "Ensure 'Password must meet complexity requirements' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-149" + Task = "Ensure 'Store passwords using reversible encryption' is set to 'Disabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#AuditPolicies.ps1 new file mode 100644 index 0000000..b303f1b --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#AuditPolicies.ps1 @@ -0,0 +1,1217 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "Medium-041" + Task = "Ensure 'Audit Computer Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Computer Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Computer Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Computer Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-042" + Task = "Ensure 'Audit Other Account Management Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-043" + Task = "Ensure 'Audit Security Group Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-044" + Task = "Ensure 'Audit User Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-045" + Task = "Ensure 'Audit Process Creation' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-046" + Task = "Ensure 'Audit Process Termination' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Process Termination + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Termination" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Termination'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-047" + Task = "Ensure 'Audit Account Lockout' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-048" + Task = "Ensure 'Audit Group Membership' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-049" + Task = "Ensure 'Audit Logoff' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-050" + Task = "Ensure 'Audit Logon' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-051" + Task = "Ensure 'Audit Other Logon/Logoff Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-052" + Task = "Ensure 'Audit Special Logon' is set to 'Success and Failure'." + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-053" + Task = "Ensure 'Audit File Share' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-054" + Task = "Ensure 'Audit File System' is set to 'Success and Failure'." + Test = { + # Get the audit policy for the subcategory File System + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File System" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File System'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-055" + Task = "Ensure 'Audit Kernel Object' is set to 'Success and Failure'." + Test = { + # Get the audit policy for the subcategory Kernel Object + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kernel Object" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kernel Object'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-056" + Task = "Ensure 'Audit Other Object Access Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-057" + Task = "Ensure 'Audit Registry' is set to 'Success and Failure'." + Test = { + # Get the audit policy for the subcategory Registry + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Registry" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Registry'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-058" + Task = "Ensure 'Audit Audit Policy Change' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-059" + Task = "Ensure 'Audit Other Policy Change Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-060" + Task = "Ensure 'Audit System Integrity' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#RegistrySettings.ps1 new file mode 100644 index 0000000..0bacceb --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#RegistrySettings.ps1 @@ -0,0 +1,12743 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$avstatus = CheckForActiveAV +$windefrunning = CheckWindefRunning +[AuditTest] @{ + Id = "High-001 A" + Task = "Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 B" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block executable content from email client and webmail'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 C" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating child processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 D" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating executable content'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 E" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block Office applications from injecting code into other processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 F" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block JavaScript or VBScript from launching downloaded executable content'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 G" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block execution of potentially obfuscated scripts'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 H" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block Win32 API calls from Office macro'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 I" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block executable files from running unless they meet a prevalence, age, or trusted list criterion'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "01443614-CD74-433A-B99E-2ECDC07BFC25" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "01443614-CD74-433A-B99E-2ECDC07BFC25" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 J" + Task = "Ensure 'Configure Attack Surface Reduction rules: Use advanced protection against ransomware'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "c1db55ab-c21a-4637-bb3f-a12568109d35" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "c1db55ab-c21a-4637-bb3f-a12568109d35" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 K" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block credential stealing from the Windows local security authority subsystem (lsass.exe))'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 L" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block process creations originating from PSExec and WMI commands)" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "D1E49AAC-8F56-4280-B9BA-993A6D77406C" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "D1E49AAC-8F56-4280-B9BA-993A6D77406C" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 M" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block untrusted and unsigned processes that run from USB' is configured" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 N" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block Office communication application from creating child processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 O" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block Adobe Reader from creating child processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-001 P" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block persistence through WMI event subscription'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-002" + Task = "Ensure 'Interactive logon' is configured 'Number of previous logons to cache (in case domain controller is not available)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "CachedLogonsCount" ` + | Select-Object -ExpandProperty "CachedLogonsCount" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-003" + Task = "Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-004" + Task = "Ensure 'WDigest Authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-005 A" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-005 B" + Task = "Ensure 'Turn On Virtualization Based Security: Select Platform Security Level' is set to 'Secure Boot and DMA Protection'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-005 C" + Task = "Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-006" + Task = "Ensure 'Configure allowed applications' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Controlled Folder Access" ` + -Name "ExploitGuard_ControlledFolderAccess_AllowedApplications" ` + | Select-Object -ExpandProperty "ExploitGuard_ControlledFolderAccess_AllowedApplications" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-007" + Task = "Ensure 'Configure Controlled folder access' is set to 'Enabled: Block'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Controlled Folder Access" ` + -Name "EnableControlledFolderAccess" ` + | Select-Object -ExpandProperty "EnableControlledFolderAccess" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-008 A" + Task = "Ensure 'Configure protected folders' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Controlled Folder Access" ` + -Name "ExploitGuard_ControlledFolderAccess_ProtectedFolders" ` + | Select-Object -ExpandProperty "ExploitGuard_ControlledFolderAccess_ProtectedFolders" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-008 B" + Task = "Ensure 'Configure protected folders' is set to 'Enter the folders that should be guarded'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Controlled Folder Access\ProtectedFolders" ` + -Name "2" ` + | Select-Object -ExpandProperty "2" + + if ($regValue -ne "*") { + return @{ + Message = "Registry value is '$regValue'. Expected: *" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-009" + Task = "Ensure 'Do not display network selection UI' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-010" + Task = "Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-011" + Task = "Ensure 'Do not display the password reveal button' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-012" + Task = "Ensure 'Enumerate administrator accounts on elevation' is set 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrator" ` + | Select-Object -ExpandProperty "EnumerateAdministrator" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-013" + Task = "Ensure 'Require trusted path for credential entry' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnableSecureCredentialPrompting" ` + | Select-Object -ExpandProperty "EnableSecureCredentialPrompting" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-014" + Task = "Ensure 'Prevent the use of security questions for local accounts' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "NoLocalPasswordResetQuestions" ` + | Select-Object -ExpandProperty "NoLocalPasswordResetQuestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-015" + Task = "Ensure 'Disable or enable software Secure Attention Sequence' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "SoftwareSASGeneration" ` + | Select-Object -ExpandProperty "SoftwareSASGeneration" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-016" + Task = "Ensure 'Sign-in and lock last interactive user automatically after a restart' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-017" + Task = "Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-018" + Task = "Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good and unknown'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-019" + Task = "Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-020" + Task = "Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableUIADesktopToggle" ` + | Select-Object -ExpandProperty "EnableUIADesktopToggle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-021" + Task = "Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-022" + Task = "Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-023" + Task = "Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-024" + Task = "Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-025" + Task = "Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-026" + Task = "Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-027" + Task = "Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-028 A" + Task = "Ensure 'Use a common set of exploit protection settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender ExploitGuard\Exploit Protection" ` + -Name "ExploitProtectionSettings" ` + | Select-Object -ExpandProperty "ExploitProtectionSettings" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-028 B" + Task = "Ensure 'Use a common set of exploit protection settings' is configured 'Type the location (local path, UNC path, or URL) of the mitigation settings configuration XML file'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender ExploitGuard\Exploit Protection" ` + -Name "ExploitProtectionSettings" ` + | Select-Object -ExpandProperty "ExploitProtectionSettings" + + if ($regValue -ne "*") { + return @{ + Message = "Registry value is '$regValue'. Expected: *" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-029" + Task = "Ensure 'Prevent users from modifying settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection" ` + -Name "DisallowExploitProtectionOverride" ` + | Select-Object -ExpandProperty "DisallowExploitProtectionOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-030" + Task = "Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-031" + Task = "Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-033" + Task = "Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-034" + Task = "Ensure 'Allow download restrictions' is set to 'Enabled: Block potentially dangerous downloads'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "DownloadRestrictions" ` + | Select-Object -ExpandProperty "DownloadRestrictions" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-035" + Task = "Ensure 'Configure Do Not Track' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\MicrosoftEdge\Main" ` + -Name "DoNotTrack" ` + | Select-Object -ExpandProperty "DoNotTrack" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-036" + Task = "Ensure 'Control the mode of DNS-over-HTTPS' is set to 'Enabled': 'Disable DNS-over-HTTPS'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "DnsOverHttpsMode" ` + | Select-Object -ExpandProperty "DnsOverHttpsMode" + + if ($regValue -ne "off") { + return @{ + Message = "Registry value is '$regValue'. Expected: off" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-037" + Task = "Ensure 'Control where developer tools can be used' is configured 'Control where developer tools can be used'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "DeveloperToolsAvailability" ` + | Select-Object -ExpandProperty "DeveloperToolsAvailability" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-038" + Task = "Ensure 'DNS interception checks enabled' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "DNSInterceptionChecksEnabled" ` + | Select-Object -ExpandProperty "DNSInterceptionChecksEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-039" + Task = "Ensure 'Default pop-up window setting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "DefaultPopupsSetting" ` + | Select-Object -ExpandProperty "DefaultPopupsSetting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-040" + Task = "Ensure 'Enable saving passwords to the password manager' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge\Recommended" ` + -Name "PasswordManagerEnabled" ` + | Select-Object -ExpandProperty "PasswordManagerEnabled" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-041" + Task = "Ensure 'Configure Microsoft Defender SmartScreen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "SmartScreenEnabled" ` + | Select-Object -ExpandProperty "SmartScreenEnabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-042" + Task = "Ensure 'Prevent bypassing Microsoft Defender SmartScreen prompts for sites' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge" ` + -Name "PreventSmartScreenPromptOverride" ` + | Select-Object -ExpandProperty "PreventSmartScreenPromptOverride" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-043" + Task = "Ensure 'Prevent bypassing of Microsoft Defender SmartScreen warnings about downloads' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge" ` + -Name "PreventSmartScreenPromptOverrideForFiles" ` + | Select-Object -ExpandProperty "PreventSmartScreenPromptOverrideForFiles" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-044" + Task = "Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-045" + Task = "Ensure 'Turn on Windows Defender Application Guard in Enterprise Mode' is set to 'Enabled: 1'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowAppHVSI_ProviderSet" ` + | Select-Object -ExpandProperty "AllowAppHVSI_ProviderSet" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-046" + Task = "Ensure 'Use the Enterprise Mode IE website list' is set to 'Enabled': 'Type the location (URL) of your Enterprise Mode IE website list'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\EnterpriseMode" ` + -Name "SiteList" ` + | Select-Object -ExpandProperty "SiteList" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-047" + Task = "Ensure 'Send all sites not included in the Enterprise Mode Site List to Microsoft Edge.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\EnterpriseMode" ` + -Name "RestrictIE" ` + | Select-Object -ExpandProperty "RestrictIE" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-048" + Task = "Ensure 'Allow Automatic Updates immediate installation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "AutoInstallMinorUpdates" ` + | Select-Object -ExpandProperty "AutoInstallMinorUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-049 A" + Task = "Ensure 'Configure Automatic Updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-049 B" + Task = " Ensure 'Configure Automatic Updates' is set to '4 - Auto download and schedule the install'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "AUOptions" ` + | Select-Object -ExpandProperty "AUOptions" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-049 C" + Task = "Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-049 D" + Task = "Ensure 'Configure Automatic Updates' is configured 'Install updates for other Microsoft products'" + Test = { + try { + $regValue1 = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\WindowsUpdate\Services" ` + -Name "DefaultService" ` + | Select-Object -ExpandProperty "DefaultService" + $regValue2 = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Services\7971F918-A847-4430-9279-4A52D1EFE18D" ` + -Name "RegisteredWithAU" ` + | Select-Object -ExpandProperty "RegisteredWithAU" + if ($regValue1 -eq "7971f918-a847-4430-9279-4a52d1efe18d" -and $regValue2 -eq 1) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException], [System.Management.Automation.ItemNotFoundException] { + try { + $regValue3 = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "AllowMUUpdateService" ` + | Select-Object -ExpandProperty "AllowMUUpdateService" + $regValue4 = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + if ($regValue3 -eq 1 -and $regValue4 -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException], [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "At least one of the following ways aren't configured correctly.
+ Configure these to paths to get compliance:
+ HKEY_LOCAL_MACHINE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Services:DefaultService = 7971f918-a847-4430-9279-4a52d1efe18d
+ HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Services\7971F918-A847-4430-9279-4A52D1EFE18D:RegisteredWithAU = 1
+ OR configure these:
+ HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU:AllowMUUpdateService = 1
+ HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU:NoAutoUpdate = 0 + " + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "High-050" + Task = "Ensure 'Do not include drivers with Windows Updates' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "ExcludeWUDriversInQualityUpdate" ` + | Select-Object -ExpandProperty "ExcludeWUDriversInQualityUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-051" + Task = "Ensure 'Enabling Windows Update Power Management to automatically wake up the system to install scheduled updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "AUPowerManagement" ` + | Select-Object -ExpandProperty "AUPowerManagement" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-052" + Task = "Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-053" + Task = "Ensure 'Remove access to use all Windows Update features' is disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\WindowsUpdate" ` + -Name "DisableWindowsUpdateAccess" ` + | Select-Object -ExpandProperty "DisableWindowsUpdateAccess" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-054" + Task = "Ensure 'Turn on recommended updates via Automatic Updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "IncludeRecommendedUpdates" ` + | Select-Object -ExpandProperty "IncludeRecommendedUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "High-055" + Task = "Ensure 'Specify intranet Microsoft update service location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "UseWUServer" ` + | Select-Object -ExpandProperty "UseWUServer" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-004" + Task = "Ensure 'Enable insecure guest logons' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-006" + Task = "Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-007" + Task = "Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-008" + Task = "Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-009" + Task = "Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-010" + Task = "Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "restrictremotesam" ` + | Select-Object -ExpandProperty "restrictremotesam" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-011" + Task = "Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-012" + Task = "Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-015" + Task = "Ensure 'Turn off Microsoft Defender AntiVirus' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "DisableAntiSpyware" ` + | Select-Object -ExpandProperty "DisableAntiSpyware" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-016" + Task = "Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-017" + Task = "Ensure 'Configure the 'Block at First Sight' feature' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "DisableBlockAtFirstSeen" ` + | Select-Object -ExpandProperty "DisableBlockAtFirstSeen" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-018" + Task = "Ensure 'Join Microsoft MAPS' is set to 'Enabled': 'Advanced MAPS'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-019" + Task = "Ensure 'Send file samples when further analysis is required' is set to 'Send safe samples'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SubmitSamplesConsent" ` + | Select-Object -ExpandProperty "SubmitSamplesConsent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-020" + Task = "Ensure 'Configure extended cloud check' is set to 'Enabled' and set to '50'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\MpEngine" ` + -Name "MpBafsExtendedTimeout" ` + | Select-Object -ExpandProperty "MpBafsExtendedTimeout" + + if ($regValue -ne 50) { + return @{ + Message = "Registry value is '$regValue'. Expected: 50" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-021" + Task = "Ensure 'Select cloud protection level' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\MpEngine" ` + -Name "MpCloudBlockLevel" ` + | Select-Object -ExpandProperty "MpCloudBlockLevel" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-022" + Task = "Ensure 'Configure removal of items from Quarantine folder' is set to 'Disabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Quarantine" ` + -Name "PurgeItemsAfterDelay" ` + | Select-Object -ExpandProperty "PurgeItemsAfterDelay" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-023" + Task = "Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-024" + Task = "Ensure 'Turn off real-time protection' is set to 'Disabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-025" + Task = "Ensure 'Turn on behavior monitoring' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-026" + Task = " Ensure 'Turn on process scanning whenever real-time protection is enabled' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableScanOnRealtimeEnable" ` + | Select-Object -ExpandProperty "DisableScanOnRealtimeEnable" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-027" + Task = "Ensure 'Allow users to pause scan' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Microsoft Antimalware\Scan" ` + -Name "AllowPause" ` + | Select-Object -ExpandProperty "AllowPause" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-028" + Task = "Ensure 'Check for the latest virus and spyware definitions before running a scheduled scan' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Microsoft Antimalware\Scan" ` + -Name "CheckForSignaturesBeforeRunningScan" ` + | Select-Object -ExpandProperty "CheckForSignaturesBeforeRunningScan" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-029" + Task = "Ensure 'Scan archive files' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableArchiveScanning" ` + | Select-Object -ExpandProperty "DisableArchiveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-030" + Task = "Ensure 'Scan packed executables' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Microsoft Antimalware\Scan" ` + -Name "DisablePackedExeScanning" ` + | Select-Object -ExpandProperty "DisablePackedExeScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-031" + Task = "Ensure 'Scan removable drives' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-032" + Task = "Ensure 'Turn on e-mail scanning' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-033" + Task = "Ensure 'Turn on heuristics' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableHeuristics" ` + | Select-Object -ExpandProperty "DisableHeuristics" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-034" + Task = "Ensure 'Do not preserve zone information in file attachments' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-035" + Task = "Ensure 'Hide mechanisms to remove zone information' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "HideZoneInfoOnProperties" ` + | Select-Object -ExpandProperty "HideZoneInfoOnProperties" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-036" + Task = "Ensure 'Include command line in process creation events' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-037" + Task = "Ensure 'Specify the maximum log file size (KB)' is configured 'Maximum Log Size (KB): 65536' (Application)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -ne 65536)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-038" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '2097152' (Security)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 2097152) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2097152" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-039" + Task = "Ensure 'Specify the maximum log file size (KB)' is configured 'Maximum Log Size (KB): 65536' (System)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -ne 65536)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-061" + Task = "Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-062" + Task = "Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-063" + Task = "Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-064" + Task = "Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-065" + Task = "Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-066" + Task = "Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-067" + Task = "Ensure 'Route all traffic through the internal network' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TCPIP\v6Transition" ` + -Name "Force_Tunneling" ` + | Select-Object -ExpandProperty "Force_Tunneling" + + if ($regValue -ne "Enabled") { + return @{ + Message = "Registry value is '$regValue'. Expected: Enabled" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-068" + Task = "Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-070" + Task = "Ensure 'Remove CD Burning features' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoCDBurning" ` + | Select-Object -ExpandProperty "NoCDBurning" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-071" + Task = "Ensure 'Prevent access to the command prompt' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\System" ` + -Name "DisableCMD" ` + | Select-Object -ExpandProperty "DisableCMD" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-072 A" + Task = "Ensure 'Prevent installation of devices that match any of these device IDs' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceIDs" ` + | Select-Object -ExpandProperty "DenyDeviceIDs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-072 B" + Task = "Ensure 'Prevent installation of devices that match any of these device IDs' is set to 'Prevent installation of devices that match any of these Device IDs: PCI\CC_0C0010'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceIDs" ` + -Name "3" ` + | Select-Object -ExpandProperty "3" + + if ($regValue -ne "PCI\CC_0C0010") { + return @{ + Message = "Registry value is '$regValue'. Expected: PCI\CC_0C0010" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-072 C" + Task = "Ensure 'Prevent installation of devices that match any of these device IDs' is set to 'Prevent installation of devices that match any of these Device IDs: PCI\CC_0C0A'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceIDs" ` + -Name "5" ` + | Select-Object -ExpandProperty "5" + + if ($regValue -ne "PCI\CC_0C0A") { + return @{ + Message = "Registry value is '$regValue'. Expected: PCI\CC_0C0A" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-072 D" + Task = "Ensure 'Prevent installation of devices that match any of these device IDs' is set to 'Also apply to matching devices that are already installed'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceIDsRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceIDsRetroactive" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-073 A" + Task = "Ensure 'Prevent installation of devices using drivers that match these device setup classes' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClasses" ` + | Select-Object -ExpandProperty "DenyDeviceClasses" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-073 B" + Task = "Prevent installation of devices using drivers that match these device setup classes: 'Prevent installation of devices using drivers for these device setup classes'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "4" ` + | Select-Object -ExpandProperty "4" + + if ($regValue -ne "{d48179be-ec20-11d1-b6b8-00c04fa372a7}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {d48179be-ec20-11d1-b6b8-00c04fa372a7}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-073 C" + Task = "Ensure 'Prevent installation of devices using drivers that match these device setup classes' is configured 'Also apply to matching devices that are already installed.'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClassesRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceClassesRetroactive" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-074 A" + Task = "Ensure 'Choose drive encryption method and cipher strength (Windows 10 [Version 1511] and later)' is set to 'Enabled': 'XTS-AES 128-bit'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "EncryptionMethodWithXtsOs" ` + | Select-Object -ExpandProperty "EncryptionMethodWithXtsOs" + + if (($regValue -ne 6)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 6" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-074 B" + Task = "Ensure 'Choose drive encryption method and cipher strength (Windows 10 [Version 1511] and later)' is set to 'XTS-AES 128-bit'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "EncryptionMethodWithXtsFdv" ` + | Select-Object -ExpandProperty "EncryptionMethodWithXtsFdv" + + if (($regValue -ne 6)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 6" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-074 C" + Task = "Ensure 'Select the encryption method for removable data drives' is configured 'XTS-AES 128-bit'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "EncryptionMethodWithXtsRdv" ` + | Select-Object -ExpandProperty "EncryptionMethodWithXtsRdv" + + if (($regValue -ne 6)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 6" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-075" + Task = "Ensure 'Disable new DMA devices when this computer is locked' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "DisableExternalDMAUnderLock" ` + | Select-Object -ExpandProperty "DisableExternalDMAUnderLock" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-076" + Task = "Ensure 'Prevent memory overwrite on restart' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "MorBehavior" ` + | Select-Object -ExpandProperty "MorBehavior" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-077 A" + Task = "Ensure 'Choose how BitLocker-protected fixed drives can be recovered' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecovery" ` + | Select-Object -ExpandProperty "FDVRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-077 B" + Task = "Ensure 'Choose how BitLocker-protected removable drives can be recovered' is set to 'Allow data recovery agent'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVManageDRA" ` + | Select-Object -ExpandProperty "FDVManageDRA" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-077 C" + Task = "Ensure 'Configure user storage of BitLocker recovery information' is set to 'Allow 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecoveryPassword" ` + | Select-Object -ExpandProperty "FDVRecoveryPassword" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-077 D" + Task = "Ensure 'Choose how BitLocker-protected removable drives can be recovered' is set to 'Allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecoveryKey" ` + | Select-Object -ExpandProperty "FDVRecoveryKey" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-077 E" + Task = "Ensure 'Choose how BitLocker-protected removable drives can be recovered' is set to 'Omit recovery options from the BitLocker setup wizard'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVHideRecoveryPage" ` + | Select-Object -ExpandProperty "FDVHideRecoveryPage" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-077 F" + Task = "Ensure 'Configure storage of BitLocker recovery information to AD DS' is set to 'Backup recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "FDVActiveDirectoryInfoToStore" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-077 G" + Task = "Ensure 'Do not enable BitLocker until recovery information is stored to AD DS for removable data drives' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "FDVRequireActiveDirectoryBackup" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-077 H" + Task = "Ensure 'Choose how BitLocker-protected removable drives can be recovered' is set to 'Save BitLocker recovery information to AD DS for fixed data drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "FDVActiveDirectoryBackup" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-078 A" + Task = "Ensure 'Configure use of passwords for fixed data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVPassphrase" ` + | Select-Object -ExpandProperty "FDVPassphrase" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-078 B" + Task = "Ensure 'Require password for fixed data drive' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVEnforcePassphrase" ` + | Select-Object -ExpandProperty "FDVEnforcePassphrase" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-078 C" + Task = "Ensure 'Configure password complexity for fixed data drives' is set to 'Require password complexity'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVPassphraseComplexity" ` + | Select-Object -ExpandProperty "FDVPassphraseComplexity" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-078 D" + Task = "Ensure 'Minimum password length for fixed data drive' is set to 14." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVPassphraseLength" ` + | Select-Object -ExpandProperty "FDVPassphraseLength" + + if (($regValue -ne 14)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 14" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-079" + Task = "Ensure 'Deny write access to fixed drives not protected by BitLocker' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\Microsoft\FVE" ` + -Name "FDVDenyWriteAccess" ` + | Select-Object -ExpandProperty "FDVDenyWriteAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-080" + Task = "Ensure 'Enforce drive encryption type on fixed data drives' is set to 'Enabled' and 'Full encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVEncryptionType" ` + | Select-Object -ExpandProperty "FDVEncryptionType" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-081" + Task = "Ensure 'Allow devices compliant with InstantGo or HSTI to opt out of pre-boot PIN.' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "OSEnablePreBootPinExceptionOnDECapableDevice" ` + | Select-Object -ExpandProperty "OSEnablePreBootPinExceptionOnDECapableDevice" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-082" + Task = "Ensure 'Allow enhanced PINs for startup' is set 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseEnhancedPin" ` + | Select-Object -ExpandProperty "UseEnhancedPin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-083" + Task = "Ensure 'Allow network unlock at startup' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSManageNKP" ` + | Select-Object -ExpandProperty "OSManageNKP" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-084" + Task = "Ensure 'Allow Secure Boot for integrity validation' is set 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "OSAllowSecureBootForIntegrity" ` + | Select-Object -ExpandProperty "OSAllowSecureBootForIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-085 A" + Task = "Ensure 'Choose how BitLocker-protected operating system drives can be recovered' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecovery" ` + | Select-Object -ExpandProperty "OSRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-085 B" + Task = "Ensure 'Choose how BitLocker-protected operating system drives can be recovered' set to 'Allow data recovery agent'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSManageDRA" ` + | Select-Object -ExpandProperty "OSManageDRA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-085 C" + Task = "Ensure 'When using ‘BitLocker Management Solution', the `"Save BitLocker recovery information to AD DS for operating system drive`" option should be unchecked' is set to 'Omit recovery options from the BitLocker setup wizard'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSHideRecoveryPage" ` + | Select-Object -ExpandProperty "OSHideRecoveryPage" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-085 D" + Task = "Ensure 'Save BitLocker recovery information to AD DS for operating system drives' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "OSActiveDirectoryBackup" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-085 E" + Task = "Ensure 'Choose how BitLocker-protected operating system drives can be recovered' set to 'Do not enable BitLocker until recovery information is stored to AD DS for operating system drives (Enabled)'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "OSRequireActiveDirectoryBackup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-086" + Task = "Ensure 'Configure minimum PIN length for startup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "MinimumPIN" ` + | Select-Object -ExpandProperty "MinimumPIN" + + if ($regValue -ne 14) { + return @{ + Message = "Registry value is '$regValue'. Expected: 14" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-087 A" + Task = "Ensure 'Configure use of passwords for operating system drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "OSPassphrase" ` + | Select-Object -ExpandProperty "OSPassphrase" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-087 B" + Task = "Ensure 'Minimum password length for operating system drive' is set to 14." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "OSPassphraseLength" ` + | Select-Object -ExpandProperty "OSPassphraseLength" + + if (($regValue -ne 14)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 14" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-087 C" + Task = "Ensure 'Configure use of passwords for operating system drives' is set to 'Require password complexity'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "OSPassphraseComplexity" ` + | Select-Object -ExpandProperty "OSPassphraseComplexity" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-088" + Task = "Ensure 'Disallow standard users from changing the PIN or password' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "DisallowStandardUserPINReset" ` + | Select-Object -ExpandProperty "DisallowStandardUserPINReset" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-089" + Task = "Ensure 'Enforce drive encryption type on operating system drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "OSEncryptionType" ` + | Select-Object -ExpandProperty "OSEncryptionType" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-090 A" + Task = "Ensure 'Require additional authentication at startup' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseAdvancedStartup" ` + | Select-Object -ExpandProperty "UseAdvancedStartup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-090 B" + Task = "Ensure 'Require additional authentication at startup' set to 'Allow BitLocker without a compatible TPM'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "EnableBDEWithNoTPM" ` + | Select-Object -ExpandProperty "EnableBDEWithNoTPM" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-090 C" + Task = "Ensure 'Require additional authentication at startup' set to 'Do not allow TPM'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPM" ` + | Select-Object -ExpandProperty "UseTPM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-090 D" + Task = "Ensure 'Configure TPM startup PIN' is set to 'Allow startup PIN with TPM'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPMPIN" ` + | Select-Object -ExpandProperty "UseTPMPIN" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-090 E" + Task = "Ensure 'Configure TPM startup key' is set so 'Allow startup key with TPM'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPMKey" ` + | Select-Object -ExpandProperty "UseTPMKey" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-090 F" + Task = "Ensure 'Configure TPM startup key and PIN' is set to 'Allow startup key and PIN with TPM'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPMKeyPIN" ` + | Select-Object -ExpandProperty "UseTPMKeyPIN" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-091" + Task = "Ensure 'Reset platform validation data after BitLocker recovery' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "TPMAutoReseal" ` + | Select-Object -ExpandProperty "TPMAutoReseal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-092 A" + Task = "Ensure 'Choose how BitLocker-protected removable drives can be recovered' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecovery" ` + | Select-Object -ExpandProperty "RDVRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-092 B" + Task = "Ensure 'Choose how BitLocker-protected removable drives can be recovered' set to 'Allow data recovery agent'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVManageDRA" ` + | Select-Object -ExpandProperty "RDVManageDRA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-092 C" + Task = "Ensure 'Configure user storage of BitLocker recovery information' is set to 'Allow 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\HKEY_LOCAL_MACHINE" ` + -Name "RDVRecoveryPassword" ` + | Select-Object -ExpandProperty "RDVRecoveryPassword" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-092 D" + Task = "Ensure 'Choose how BitLocker-protected removable drives can be recovered' is set to 'Allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecoveryKey" ` + | Select-Object -ExpandProperty "RDVRecoveryKey" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-092 E" + Task = "Ensure 'Choose how BitLocker-protected removable drives can be recovered' set to 'Omit recovery options from the BitLocker setup wizard (True)'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVHideRecoveryPage" ` + | Select-Object -ExpandProperty "RDVHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-092 F" + Task = "Ensure 'Choose how BitLocker-protected removable drives can be recovered' set to 'Save BitLocker recovery information to AD DS for removable data drives'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "RDVActiveDirectoryBackup" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-092 G" + Task = "Ensure 'Choose how BitLocker-protected removable drives can be recovered: Configure storage of BitLocker recovery information to AD DS:' is set to 'Enabled: Backup recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "RDVActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-092 H" + Task = "Ensure 'Choose how BitLocker-protected removable drives can be recovered' is set to 'Do not enable BitLocker until recovery information is stored to AD DS for removable data drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "RDVRequireActiveDirectoryBackup" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-093 A" + Task = "Ensure 'Configure use of passwords for removable data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVPassphrase" ` + | Select-Object -ExpandProperty "RDVPassphrase" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-093 B" + Task = "Ensure 'Configure use of passwords for removable data drives' is set to 'Require password for removable data drive'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVEnforcePassphrase" ` + | Select-Object -ExpandProperty "RDVEnforcePassphrase" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-093 C" + Task = "Ensure 'Configure use of passwords for removable data drives' is set to 'Configure password complexity for removable data drives: Require password complexity'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVPassphraseComplexity" ` + | Select-Object -ExpandProperty "RDVPassphraseComplexity" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-093 D" + Task = "Ensure 'Configure use of passwords for removable data drives' is set to 'Minimum password length for removable data drive: 14'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVPassphraseLength" ` + | Select-Object -ExpandProperty "RDVPassphraseLength" + + if (($regValue -ne 14)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 14" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-094 A" + Task = "Ensure 'Control use of BitLocker on removable drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVConfigureBDE" ` + | Select-Object -ExpandProperty "RDVConfigureBDE" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-094 B" + Task = "Ensure 'Control use of BitLocker on removable drives' is set to 'Allow users to suspend and decrypt BitLocker protection on removable data drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVDisableBDE" ` + | Select-Object -ExpandProperty "RDVDisableBDE" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-095" + Task = "Ensure 'Deny write access to removable drives not protected by BitLocker' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\Microsoft\FVE" ` + -Name "RDVDenyWriteAccess" ` + | Select-Object -ExpandProperty "RDVDenyWriteAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-096" + Task = "Ensure 'Enforce drive encryption type on removable data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVEncryptionType" ` + | Select-Object -ExpandProperty "RDVEncryptionType" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-097" + Task = "Ensure 'Interactive logon: Machine account lockout threshold' is set to '10 or fewer invalid logon attempts, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MaxDevicePasswordFailedAttempts" ` + | Select-Object -ExpandProperty "MaxDevicePasswordFailedAttempts" + + if (($regValue -gt 10 -or $regValue -le 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 10 and x > 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-098" + Task = "Ensure 'All Removable Storage classes: Deny all access' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices" ` + -Name "Deny_All" ` + | Select-Object -ExpandProperty "Deny_All" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-099" + Task = "Ensure 'CD and DVD: Deny execute access' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{53f56308-b6bf-11d0-94f2-00a0c91efb8b}" ` + -Name "Deny_Execute" ` + | Select-Object -ExpandProperty "Deny_Execute" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-100" + Task = "Ensure 'CD and DVD: Deny read access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{53f56308-b6bf-11d0-94f2-00a0c91efb8b}" ` + -Name "Deny_Read" ` + | Select-Object -ExpandProperty "Deny_Read" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-101" + Task = "Ensure 'CD and DVD: Deny write access' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{53f56308-b6bf-11d0-94f2-00a0c91efb8b}" ` + -Name "Deny_Write" ` + | Select-Object -ExpandProperty "Deny_Write" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-102" + Task = "Ensure 'Custom Classes: Deny read access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\RemovableStorageDevices\Custom\Deny_Read" ` + -Name "Deny_Read" ` + | Select-Object -ExpandProperty "Deny_Read" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-103" + Task = "Ensure 'Custom Classes: Deny write access' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\RemovableStorageDevices\Custom\Deny_Write" ` + -Name "Deny_Write" ` + | Select-Object -ExpandProperty "Deny_Write" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-104" + Task = " Ensure 'Floppy Drives: Deny execute access' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{53f56311-b6bf-11d0-94f2-00a0c91efb8b}" ` + -Name "Deny_Execute" ` + | Select-Object -ExpandProperty "Deny_Execute" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-105" + Task = " Ensure 'Floppy Drives: Deny read access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{53f56311-b6bf-11d0-94f2-00a0c91efb8b}" ` + -Name "Deny_Read" ` + | Select-Object -ExpandProperty "Deny_Read" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-106" + Task = " Ensure 'Floppy Drives: Deny write access' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{53f56311-b6bf-11d0-94f2-00a0c91efb8b}" ` + -Name "Deny_Write" ` + | Select-Object -ExpandProperty "Deny_Write" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-107" + Task = "Ensure 'Removable Disks: Deny execute access' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}" ` + -Name "Deny_Execute" ` + | Select-Object -ExpandProperty "Deny_Execute" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-108" + Task = " Ensure 'Removable Disks: Deny read access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}" ` + -Name "Deny_Read" ` + | Select-Object -ExpandProperty "Deny_Read" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-109" + Task = " Ensure 'Removable Disks: Deny write access' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}" ` + -Name "Deny_Write" ` + | Select-Object -ExpandProperty "Deny_Write" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-110" + Task = "Ensure 'Tape Drives: Deny execute access' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{53f5630b-b6bf-11d0-94f2-00a0c91efb8b}" ` + -Name "Deny_Execute" ` + | Select-Object -ExpandProperty "Deny_Execute" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-111" + Task = "Ensure 'Tape Drives: Deny read access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{53f5630b-b6bf-11d0-94f2-00a0c91efb8b}" ` + -Name "Deny_Read" ` + | Select-Object -ExpandProperty "Deny_Read" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-112" + Task = " Ensure 'Tape Drives: Deny write access' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{53f5630b-b6bf-11d0-94f2-00a0c91efb8b}" ` + -Name "Deny_Write" ` + | Select-Object -ExpandProperty "Deny_Write" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-113 A" + Task = " Ensure 'WPD Devices: Deny read access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{6AC27878-A6FA-4155-BA85-F98F491D4F33}" ` + -Name "Deny_Read" ` + | Select-Object -ExpandProperty "Deny_Read" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-113 B" + Task = " Ensure 'WPD Devices: Deny read access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{F33FDC04-D1AC-4E8E-9A30-19BBD4B108AE}" ` + -Name "Deny_Read" ` + | Select-Object -ExpandProperty "Deny_Read" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-114 A" + Task = "Ensure 'WPD Devices: Deny write access' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{6AC27878-A6FA-4155-BA85-F98F491D4F33}" ` + -Name "Deny_Write" ` + | Select-Object -ExpandProperty "Deny_Write" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-114 B" + Task = "Ensure 'WPD Devices: Deny write access' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\RemovableStorageDevices\{F33FDC04-D1AC-4E8E-9A30-19BBD4B108AE}" ` + -Name "Deny_Write" ` + | Select-Object -ExpandProperty "Deny_Write" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-115" + Task = "Ensure 'Prevent the computer from joining a homegroup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HomeGroup" ` + -Name "DisableHomeGroup" ` + | Select-Object -ExpandProperty "DisableHomeGroup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-116" + Task = "Ensure 'Prevent users from sharing files within their profile.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInplaceSharing" ` + | Select-Object -ExpandProperty "NoInplaceSharing" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-117 A" + Task = "Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`" and `"Require Integrity`" set for all NETLOGON and SYSVOL shares' (\\*\NETLOGON)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if ($regValue -eq $null) { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object { $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-117 B" + Task = "Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`" and `"Require Integrity`" set for all NETLOGON and SYSVOL shares' (\\*\SYSVOL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if ($regValue -eq $null) { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object { $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-118" + Task = "Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{b973a728-3951-46bc-86fa-7877b6d5f1f1}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-119" + Task = "Ensure 'Configure security policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-120" + Task = "Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableBkGndGroupPolicy" ` + | Select-Object -ExpandProperty "DisableBkGndGroupPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-121" + Task = "Ensure 'Turn off Local Group Policy Objects processing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DisableLGPOProcessing" ` + | Select-Object -ExpandProperty "DisableLGPOProcessing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-122 A" + Task = "Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-122 B" + Task = "Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-123" + Task = "Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (ShellSmartScreenLevel)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-124" + Task = "Ensure 'Allow user control over installs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-125" + Task = "Ensure 'Always install with elevated privileges' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-126" + Task = "Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-128" + Task = "Ensure 'Always install with elevated privileges' is set to 'Disabled' (AlwaysInstallElevated)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-129" + Task = "Ensure 'Do not process the legacy run list' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "DisableLocalMachineRun" ` + | Select-Object -ExpandProperty "DisableLocalMachineRun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-130" + Task = "Ensure 'Do not process the run once list' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "DisableLocalMachineRunOnce" ` + | Select-Object -ExpandProperty "DisableLocalMachineRunOnce" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-131" + Task = "Ensure 'Run these programs at user logon' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run" ` + -Name "23" ` + | Select-Object -ExpandProperty "23" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-132" + Task = "Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount" ` + -Name "DisableUserAuth" ` + | Select-Object -ExpandProperty "DisableUserAuth" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-133" + Task = "Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-134" + Task = "Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "NoConnectedUser" ` + | Select-Object -ExpandProperty "NoConnectedUser" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-135" + Task = "Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-136" + Task = "Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-137" + Task = "Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-138" + Task = "Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-139" + Task = "Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if (($regValue -ne 2147483644) -and ($regValue -ne 2147483640)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2147483644 or x == 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-140" + Task = "Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM&NTLM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-141" + Task = "Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-142" + Task = "Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-143" + Task = "Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-144" + Task = "Ensure 'Turn off picture password sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "BlockDomainPicturePassword" ` + | Select-Object -ExpandProperty "BlockDomainPicturePassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-145" + Task = "Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-150" + Task = "Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-151" + Task = "Ensure 'Allow Standby States (S1-S3) When Sleeping (On Battery)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-152" + Task = "Ensure 'Allow Standby States (S1-S3) When Sleeping (Plugged In)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-153" + Task = "Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\d72ad9cc-1704-43b0-95d7-bda7b5432eea" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-154" + Task = "Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-155" + Task = "Ensure 'Specify the system hibernate timeout (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\9D7815A6-7EE4-497E-8888-515A05F02364" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-156" + Task = "Ensure 'Specify the system hibernate timeout (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\9D7815A6-7EE4-497E-8888-515A05F02364" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-157" + Task = "Ensure 'Specify the system sleep timeout (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\29F6C1DB-86DA-48C5-9FDB-F2B67B1F44DA" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-158" + Task = " Ensure 'Specify the system sleep timeout (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\29F6C1DB-86DA-48C5-9FDB-F2B67B1F44DA" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-159" + Task = "Ensure 'Specify the unattended sleep timeout (on battery)' is set to 'Enabled: Unattended Sleep Timeout (seconds): 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\7bc4a2f9-d8fc-4469-b07b-33eb785aaca0" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-160" + Task = "Ensure 'Specify the unattended sleep timeout (plugged in)' is set to 'Enabled' and '0 seconds'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\7bc4a2f9-d8fc-4469-b07b-33eb785aaca0" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-161" + Task = "Ensure 'Turn off hybrid sleep (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\94ac6d29-73ce-41a6-809f-6363ba21b47e" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-162" + Task = " Ensure 'Turn off hybrid sleep (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\94ac6d29-73ce-41a6-809f-6363ba21b47e" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-163" + Task = "Ensure 'Show hibernate in the power options menu' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "ShowHibernateOption" ` + | Select-Object -ExpandProperty "ShowHibernateOption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-164" + Task = "Ensure 'Show sleep in the power options menu' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "ShowSleepOption" ` + | Select-Object -ExpandProperty "ShowSleepOption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-165" + Task = "Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-166 A" + Task = "Ensure 'Turn on Script Execution' is set to 'Enabled: Allow only signed scripts'. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\PowerShell" ` + -Name "ExecutionPolicy" ` + | Select-Object -ExpandProperty "ExecutionPolicy" + + if ($regValue -ne "AllSigned") { + return @{ + Message = "Registry value is '$regValue'. Expected: AllSigned" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-166 B" + Task = "Ensure 'Turn on Script Execution' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell" ` + -Name "EnableScripts" ` + | Select-Object -ExpandProperty "EnableScripts" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-167" + Task = "Ensure 'Prevent access to registry editing tools' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableRegistryTools" ` + | Select-Object -ExpandProperty "DisableRegistryTools" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-168" + Task = "Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-169" + Task = "Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-170" + Task = "Ensure 'Allow users to connect remotely by using Remote Desktop Services' set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDenyTSConnections" ` + | Select-Object -ExpandProperty "fDenyTSConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-172" + Task = "Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-173" + Task = "Ensure 'Configure server authentication for client' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "AuthenticationLevel" ` + | Select-Object -ExpandProperty "AuthenticationLevel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-174" + Task = "Ensure 'Do not allow passwords to be saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-175" + Task = "Ensure 'Allow users to connect remotely by using Remote Desktop Services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDenyTSConnections" ` + | Select-Object -ExpandProperty "fDenyTSConnections" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-176" + Task = "Ensure 'Deny logoff of an administrator logged in to the console session' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableForcibleLogoff" ` + | Select-Object -ExpandProperty "fDisableForcibleLogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-177" + Task = "Ensure 'Do not allow Clipboard redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableClip" ` + | Select-Object -ExpandProperty "fDisableClip" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-178" + Task = "Ensure 'Do not allow drive redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-179" + Task = "Ensure 'Always prompt for password upon connection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-180" + Task = "Ensure 'Do not allow local administrators to customize permissions' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fWritableTSCCPermTab" ` + | Select-Object -ExpandProperty "fWritableTSCCPermTab" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-181" + Task = "Ensure 'Require secure RPC communication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-182" + Task = "Ensure 'Require use of specific security layer for remote (RDP) connections' is set to 'Enabled: SSL'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SecurityLayer" ` + | Select-Object -ExpandProperty "SecurityLayer" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-183" + Task = "Ensure 'Require user authentication for remote connections by using Network Level Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "UserAuthentication" ` + | Select-Object -ExpandProperty "UserAuthentication" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-184" + Task = "Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-187" + Task = "Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-188" + Task = "Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-189" + Task = "Ensure 'Turn off Inventory Collector' is set to 'Enabled'" + Test = { + try { + $status = get-service -name pcasvc -ErrorAction Stop + if($status.Status -ne "Stopped"){ + return @{ + Message = "Compliant - AppCompat Service is disabled (no inventory data will be collected)." + Status = "True" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppCompat" ` + -Name "DisableInventory" ` + | Select-Object -ExpandProperty "DisableInventory" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + catch [System.SystemException]{ + return @{ + Message = "Service not found!" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-190" + Task = "Ensure 'Turn off Steps Recorder' is set to 'Enabled'" + Test = { + try { + $status = get-service -name pcasvc -ErrorAction Stop + if($status.Status -ne "Stopped"){ + return @{ + Message = "Compliant - AppCompat Service is disabled (no inventory data will be collected)." + Status = "True" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppCompat" ` + -Name "DisableUAR" ` + | Select-Object -ExpandProperty "DisableUAR" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + catch [System.SystemException]{ + return @{ + Message = "Service not found!" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-191" + Task = "Ensure 'Allow Telemetry' is set to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + $saferClients = @("*Server*", "*Education*", "*Enterprise*") + $productname = Get-ComputerInfo | select -ExpandProperty OsName + if (($productname -notcontains $saferClients) -and ($regValue -eq 1)) { + return @{ + Message = "Registry value is '$regValue'. Your OS $productname does not support 'Diagnostic data off'." + Status = "Warning" + } + } + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-192 A" + Task = "Ensure 'Configure Corporate Windows Error Reporting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "CorporateWerServer" ` + | Select-Object -ExpandProperty "CorporateWerServer" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-192 B" + Task = "Ensure 'Configure Corporate Windows Error Reporting' is set to 'Connect using SSL'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "CorporateWerUseSSL" ` + | Select-Object -ExpandProperty "CorporateWerUseSSL" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-192 C" + Task = "Ensure 'Configure Corporate Windows Error Reporting' has configured Server Port" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "CorporateWerPortNumber" ` + | Select-Object -ExpandProperty "CorporateWerPortNumber" + + if (($regValue -lt 0 -or $regValue -gt 65535)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 0 and x <= 65535" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-193" + Task = "Ensure 'SafeModeBlockNonAdmins' is set to 1" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "SafeModeBlockNonAdmins" ` + | Select-Object -ExpandProperty "SafeModeBlockNonAdmins" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-194" + Task = "Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-195" + Task = "Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-196" + Task = "Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-197" + Task = "Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-198" + Task = "Ensure 'Turn off multicast name resolution' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-199" + Task = "Ensure 'Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config" ` + -Name "AutoConnectAllowedOEM" ` + | Select-Object -ExpandProperty "AutoConnectAllowedOEM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-200" + Task = "Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-201" + Task = "Ensure 'Turn off heap termination on corruption' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-202" + Task = "Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-203" + Task = "Ensure 'Prevent downloading of enclosures' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-204" + Task = "Ensure 'Allow indexing of encrypted files' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-205" + Task = "Ensure 'Enables or disables Windows Game Recording and Broadcasting' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR" ` + -Name "AllowGameDVR" ` + | Select-Object -ExpandProperty "AllowGameDVR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-206" + Task = "Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-207" + Task = "Ensure 'Domain member: Maximum machine account password age' is set to '30 or fewer days, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if (($regValue -le 0 -or $regValue -gt 30)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x > 0 and x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-209" + Task = "Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-210" + Task = "Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-211" + Task = "Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-212" + Task = "Ensure 'Configure SMB v1 server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-213" + Task = "Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Medium-214" + Task = "Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True) { + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Medium-215" + Task = "Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-216" + Task = "Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if (($regValue -gt 15 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-217" + Task = "Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Medium-218" + Task = "Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True) { + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Medium-219" + Task = "Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-220" + Task = "Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-221" + Task = "Ensure 'Allow users to select when a password is required when resuming from connected standby' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainDelayLock" ` + | Select-Object -ExpandProperty "AllowDomainDelayLock" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-222" + Task = "Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-223" + Task = "Ensure 'Show lock in the user tile menu' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "ShowLockOption" ` + | Select-Object -ExpandProperty "ShowLockOption" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-224" + Task = "Ensure 'Allow Windows Ink Workspace' is set to 'On, but disallow access above lock'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-225" + Task = "Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-226" + Task = "Ensure 'Enable screen saver' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaveActive" ` + | Select-Object -ExpandProperty "ScreenSaveActive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-227" + Task = "Ensure 'Password protect the screen saver' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaverIsSecure" ` + | Select-Object -ExpandProperty "ScreenSaverIsSecure" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-228" + Task = "Ensure 'Screen saver timeout' is set to 'Enabled: 900 seconds or fewer, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaveTimeOut" ` + | Select-Object -ExpandProperty "ScreenSaveTimeOut" + + if (($regValue -lt 0 -or $regValue -gt 599940)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 0 and x <= 599940" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-229" + Task = "Ensure 'Turn off toast notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-230" + Task = "Ensure 'Do not suggest third-party content in Windows spotlight' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-231" + Task = "Ensure 'Do not allow Sound Recorder to run' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\SoundRecorder" ` + -Name "Soundrec" ` + | Select-Object -ExpandProperty "Soundrec" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-254" + Task = "Ensure 'Allow Basic authentication' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-255" + Task = "Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-256" + Task = "Ensure 'Disallow Digest authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-257" + Task = "Ensure 'Allow Basic authentication' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-258" + Task = "Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-259" + Task = "Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-260" + Task = "Ensure 'Allow Remote Shell Access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service\WinRS" ` + -Name "AllowRemoteShellAccess" ` + | Select-Object -ExpandProperty "AllowRemoteShellAccess" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-261" + Task = "Ensure 'Allow Cortana' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCortana" ` + | Select-Object -ExpandProperty "AllowCortana" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-262" + Task = "Ensure 'Don’t search the web or display web results in Search' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "ConnectedSearchUseWeb" ` + | Select-Object -ExpandProperty "ConnectedSearchUseWeb" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-263" + Task = "Ensure 'Use FIPS compliant algorithms for encryption, hashing and signing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Centrify\CentrifyDC\Settings\Fips" ` + -Name "fips.mode.enable" ` + | Select-Object -ExpandProperty "fips.mode.enable" + + if ($regValue -ne "true") { + return @{ + Message = "Registry value is '$regValue'. Expected: true" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Low-001" + Task = "Ensure 'Remove Security tab' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoSecurityTab" ` + | Select-Object -ExpandProperty "NoSecurityTab" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Low-002" + Task = "Ensure 'Turn off location' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Low-003" + Task = "Ensure 'Turn off location scripting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocationScripting" ` + | Select-Object -ExpandProperty "DisableLocationScripting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Low-004" + Task = "Ensure 'Turn off Windows Location Provider' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableWindowsLocationProvider" ` + | Select-Object -ExpandProperty "DisableWindowsLocationProvider" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Low-005" + Task = "Ensure 'Turn off access to the Store' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoUseStoreOpenWith" ` + | Select-Object -ExpandProperty "NoUseStoreOpenWith" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Low-006" + Task = "Ensure 'Turn off the Store application' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "RemoveWindowsStore" ` + | Select-Object -ExpandProperty "RemoveWindowsStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Low-007" + Task = "Ensure 'Determine if interactive users can generate Resultant Set of Policy data' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DenyRsopToInteractiveUser" ` + | Select-Object -ExpandProperty "DenyRsopToInteractiveUser" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#SecurityOptions.ps1 new file mode 100644 index 0000000..7f15ad4 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#SecurityOptions.ps1 @@ -0,0 +1,110 @@ +[AuditTest] @{ + Id = "High-032" + Task = "Ensure 'Accounts: Administrator account status' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableAdminAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableAdminAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-005" + Task = "Ensure 'Network access: Allow anonymous SID/Name translation' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-069" + Task = "Ensure 'Accounts: Guest account status' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Medium-208" + Task = "Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["ForceLogoffWhenHourExpire"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 1) { + return @{ + Message = "'ForceLogoffWhenHourExpire' currently set to: $setOption. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#UserRights.ps1 new file mode 100644 index 0000000..622ad50 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-ACSC-21H1#UserRights.ps1 @@ -0,0 +1,926 @@ +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and + (Get-WindowsOptionalFeature -Online -FeatureName "Microsoft-Hyper-V").State -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "Medium-013" + Task = "Ensure 'Access this computer from the network' is set to 'Administrators, Remote Desktop Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-014" + Task = "Ensure 'Deny access to this computer from the network' is set to 'NT AUTHORITY\Local Account'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeDenyNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-040" + Task = "Ensure 'Manage auditing and security log' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-171" + Task = "Ensure 'Deny log on through Remote Desktop Services' is set to 'Administrators, NT AUTHORITY\Local Account'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeDenyRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-185" + Task = "Ensure 'Allow log on through Remote Desktop Services' is set to 'Remote Desktop Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-232" + Task = "Ensure 'Back up files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-233" + Task = "Ensure 'Restore files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-234" + Task = "Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-235" + Task = "Ensure 'Act as part of the operating system' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-236" + Task = "Ensure 'Allow log on locally' is set to 'Administrators, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-240" + Task = "Ensure 'Create a pagefile' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-241" + Task = "Ensure 'Create a token object' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-242" + Task = "Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-243" + Task = "Ensure 'Create permanent shared objects' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-244" + Task = "Ensure 'Debug programs' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-245" + Task = "Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-246" + Task = "Ensure 'Force shutdown from a remote system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-247" + Task = "Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE, IIS_IUSRS' [IIS Role installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + "S-1-5-6" + "S-1-5-32-568" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-248" + Task = "Ensure 'Load and unload device drivers' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-249" + Task = "Ensure 'Lock pages in memory' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-250" + Task = "Ensure 'Modify firmware environment values' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-251" + Task = "Ensure 'Perform volume maintenance tasks' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-252" + Task = "Ensure 'Profile single process' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "Medium-253" + Task = "Ensure 'Take ownership of files or other objects' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#AccountPolicies.ps1 new file mode 100644 index 0000000..f6c9c43 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#AccountPolicies.ps1 @@ -0,0 +1,283 @@ +[AuditTest] @{ + Id = "1.1.1" + Task = "(L1) Ensure 'Enforce password history' is set to '24 or more password(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "(L1) Ensure 'Maximum password age' is set to '365 or fewer days, but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -gt 365 -or $setPolicy -le 0) { + if($setPolicy -eq -1){ #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 365 days and x > 0 days" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "(L1) Ensure 'Minimum password age' is set to '1 or more day(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -lt 1) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1 days" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "(L1) Ensure 'Minimum password length' is set to '14 or more character(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.5" + Task = "(L1) Ensure 'Password must meet complexity requirements' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.7" + Task = "(L1) Ensure 'Store passwords using reversible encryption' is set to 'Disabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "(L1) Ensure 'Account lockout duration' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15 -or $setPolicy -gt 99999)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15 minutes and x <= 99999 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "(L1) Ensure 'Account lockout threshold' is set to '5 or fewer invalid logon attempt(s), but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 5 -or $setPolicy -le 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 5 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.3" + Task = "(L1) Ensure 'Allow Administrator account lockout' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["AllowAdministratorLockout"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'AllowAdministratorLockout' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.4" + Task = "(L1) Ensure 'Reset account lockout counter after' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 99999 -or $setPolicy -lt 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x <= 99999 minutes and x >= 15 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#AuditPolicies.ps1 new file mode 100644 index 0000000..01bc89f --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#AuditPolicies.ps1 @@ -0,0 +1,1616 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "17.1.1" + Task = "(L1) Ensure 'Audit Credential Validation' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.1" + Task = "(L1) Ensure 'Audit Application Group Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Application Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Application Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Application Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.2" + Task = "(L1) Ensure 'Audit Security Group Management' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.3" + Task = "(L1) Ensure 'Audit User Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.1" + Task = "(L1) Ensure 'Audit PNP Activity' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.2" + Task = "(L1) Ensure 'Audit Process Creation' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.1" + Task = "(L1) Ensure 'Audit Account Lockout' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.2" + Task = "(L1) Ensure 'Audit Group Membership' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.3" + Task = "(L1) Ensure 'Audit Logoff' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.4" + Task = "(L1) Ensure 'Audit Logon' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.5" + Task = "(L1) Ensure 'Audit Other Logon/Logoff Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.6" + Task = "(L1) Ensure 'Audit Special Logon' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.1" + Task = "(L1) Ensure 'Audit Detailed File Share' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.2" + Task = "(L1) Ensure 'Audit File Share' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.3" + Task = "(L1) Ensure 'Audit Other Object Access Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.4" + Task = "(L1) Ensure 'Audit Removable Storage' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.1" + Task = "(L1) Ensure 'Audit Audit Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.2" + Task = "(L1) Ensure 'Audit Authentication Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.3" + Task = "(L1) Ensure 'Audit Authorization Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.4" + Task = "(L1) Ensure 'Audit MPSSVC Rule-Level Policy Change' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Mpssvc Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Mpssvc Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Mpssvc Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.5" + Task = "(L1) Ensure 'Audit Other Policy Change Events' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.8.1" + Task = "(L1) Ensure 'Audit Sensitive Privilege Use' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.1" + Task = "(L1) Ensure 'Audit IPsec Driver' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Ipsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Ipsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Ipsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.2" + Task = "(L1) Ensure 'Audit Other System Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.3" + Task = "(L1) Ensure 'Audit Security State Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.4" + Task = "(L1) Ensure 'Audit Security System Extension' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.5" + Task = "(L1) Ensure 'Audit System Integrity' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#RegistrySettings.ps1 new file mode 100644 index 0000000..734c19b --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#RegistrySettings.ps1 @@ -0,0 +1,17452 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$avstatus = CheckForActiveAV +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "1.1.6" + Task = "(L1) Ensure 'Relax minimum password length limits' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SAM" ` + -Name "RelaxMinimumPasswordLengthLimits" ` + | Select-Object -ExpandProperty "RelaxMinimumPasswordLengthLimits" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.1" + Task = "(L1) Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "NoConnectedUser" ` + | Select-Object -ExpandProperty "NoConnectedUser" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.3" + Task = "(L1) Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.1" + Task = "(L1) Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.2" + Task = "(L1) Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "CrashOnAuditFail" ` + | Select-Object -ExpandProperty "CrashOnAuditFail" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4.1" + Task = "(L2) Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.1" + Task = "(L1) Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.2" + Task = "(L1) Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.3" + Task = "(L1) Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.4" + Task = "(L1) Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.5" + Task = "(L1) Ensure 'Domain member: Maximum machine account password age' is set to '30 or fewer days, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if (($regValue -le 0 -or $regValue -gt 30)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x > 0 and x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.6" + Task = "(L1) Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.1" + Task = "(L1) Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.2" + Task = "(L1) Ensure 'Interactive logon: Don't display last signed-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.3" + Task = "(BL) Ensure 'Interactive logon: Machine account lockout threshold' is set to '10 or fewer invalid logon attempts, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MaxDevicePasswordFailedAttempts" ` + | Select-Object -ExpandProperty "MaxDevicePasswordFailedAttempts" + + if (($regValue -gt 10 -or $regValue -le 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 10 and x > 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.4" + Task = "(L1) Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.5" + Task = "(L1) Configure 'Interactive logon: Message text for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.6" + Task = "(L1) Configure 'Interactive logon: Message title for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.7" + Task = "(L2) Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "CachedLogonsCount" ` + | Select-Object -ExpandProperty "CachedLogonsCount" + + if ($regValue -notmatch "^[43210]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[43210]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.8" + Task = "(L1) Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if (($regValue -gt 14 -or $regValue -lt 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 14 and x >= 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.9" + Task = "(L1) Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -notmatch "^(1|2|3)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(1|2|3)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.8.1" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.2" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.3" + Task = "(L1) Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.1" + Task = "(L1) Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if (($regValue -gt 15)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.2" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.3" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.4" + Task = "(L1) Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "enableforcedlogoff" ` + | Select-Object -ExpandProperty "enableforcedlogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.5" + Task = "(L1) Ensure 'Microsoft network server: Server SPN target name validation level' is set to 1 - 'Accept if provided by client' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "SMBServerNameHardeningLevel" ` + | Select-Object -ExpandProperty "SMBServerNameHardeningLevel" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.2" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.3" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.4" + Task = "(L1) Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.5" + Task = "(L1) Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.6" + Task = "(L1) Ensure 'Network access: Named Pipes that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.7" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\ProductOptions" + "System\CurrentControlSet\Control\Server Applications" + "Software\Microsoft\Windows NT\CurrentVersion" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\ProductOptions System\CurrentControlSet\Control\Server Applications Software\Microsoft\Windows NT\CurrentVersion" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.8" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9" + Task = "(L1) Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.10" + Task = "(L1) Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "restrictremotesam" ` + | Select-Object -ExpandProperty "restrictremotesam" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.11" + Task = "(L1) Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionShares" ` + | Select-Object -ExpandProperty "NullSessionShares" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.12" + Task = "(L1) Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.1" + Task = "(L1) Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.2" + Task = "(L1) Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.3" + Task = "(L1) Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.4" + Task = "(L1) Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.5" + Task = "(L1) Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.7" + Task = "(L1) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.8" + Task = "(L1) Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.9" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.10" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if (($regValue -ne 537395200)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.11" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Audit Incoming NTLM Traffic' is set to 'Enable auditing for all accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AuditReceivingNTLMTraffic" ` + | Select-Object -ExpandProperty "AuditReceivingNTLMTraffic" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.12" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers' is set to 'Audit all' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "RestrictSendingNTLMTraffic" ` + | Select-Object -ExpandProperty "RestrictSendingNTLMTraffic" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.14.1" + Task = "(L2) Ensure 'System cryptography: Force strong key protection for user keys stored on the computer' is set to 1 - 'User is prompted when the key is first used' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography" ` + -Name "ForceKeyProtection" ` + | Select-Object -ExpandProperty "ForceKeyProtection" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.1" + Task = "(L1) Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.2" + Task = "(L1) Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.1" + Task = "(L1) Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.2" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 2 - 'Prompt for consent on the secure desktop' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.3" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.4" + Task = "(L1) Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.5" + Task = "(L1) Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.6" + Task = "(L1) Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.7" + Task = "(L1) Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.8" + Task = "(L1) Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1" + Task = "(L2) Ensure 'Bluetooth Audio Gateway Service (BTAGService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTAGService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2" + Task = "(L2) Ensure 'Bluetooth Support Service (bthserv)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bthserv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.3" + Task = "(L1) Ensure 'Computer Browser (Browser)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.4" + Task = "(L2) Ensure 'Downloaded Maps Manager (MapsBroker)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MapsBroker" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.5" + Task = "(L2) Ensure 'Geolocation Service (lfsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lfsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.6" + Task = "(L1) Ensure 'IIS Admin Service (IISADMIN)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IISADMIN" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.7" + Task = "(L1) Ensure 'Infrared monitor service (irmon)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\irmon" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.8" + Task = "(L1) Ensure 'Internet Connection Sharing (ICS) (SharedAccess)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.9" + Task = "(L2) Ensure 'Link-Layer Topology Discovery Mapper (lltdsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lltdsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.10" + Task = "(L1) Ensure 'LxssManager (LxssManager)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $result = Get-WindowsOptionalFeature -online -FeatureName Microsoft-Windows-Subsystem-Linux + $state = $result.State + if($state -eq "Disabled" -or $state -eq "Not Installed"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + else{ + return @{ + Message = "Registry value is '$state'. Expected: 'Disabled' or 'Not Installed'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException]{ + return @{ + Message = "Value not found." + Status = "Error" + } + } + } +} +[AuditTest] @{ + Id = "5.11" + Task = "(L1) Ensure 'Microsoft FTP Service (FTPSVC)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FTPSVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.12" + Task = "(L2) Ensure 'Microsoft iSCSI Initiator Service (MSiSCSI)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSiSCSI" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.13" + Task = "(L1) Ensure 'OpenSSH SSH Server (sshd)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sshd" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.14" + Task = "(L2) Ensure 'Peer Name Resolution Protocol (PNRPsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.15" + Task = "(L2) Ensure 'Peer Networking Grouping (p2psvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2psvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.16" + Task = "(L2) Ensure 'Peer Networking Identity Manager (p2pimsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2pimsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.17" + Task = "(L2) Ensure 'PNRP Machine Name Publication Service (PNRPAutoReg)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPAutoReg" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.18" + Task = "(L2) Ensure 'Print Spooler (Spooler)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.19" + Task = "(L2) Ensure 'Problem Reports and Solutions Control Panel Support (wercplsupport)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wercplsupport" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.20" + Task = "(L2) Ensure 'Remote Access Auto Connection Manager (RasAuto)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasAuto" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.21" + Task = "(L2) Ensure 'Remote Desktop Configuration (SessionEnv)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SessionEnv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.22" + Task = "(L2) Ensure 'Remote Desktop Services (TermService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.23" + Task = "(L2) Ensure 'Remote Desktop Services UserMode Port Redirector (UmRdpService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UmRdpService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.24" + Task = "(L1) Ensure 'Remote Procedure Call (RPC) Locator (RpcLocator)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcLocator" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.25" + Task = "(L2) Ensure 'Remote Registry (RemoteRegistry)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteRegistry" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.26" + Task = "(L1) Ensure 'Routing and Remote Access (RemoteAccess)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.27" + Task = "(L2) Ensure 'Server (LanmanServer)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.28" + Task = "(L1) Ensure 'Simple TCP/IP Services (simptcp)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\simptcp" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.29" + Task = "(L2) Ensure 'SNMP Service (SNMP)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SNMP" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.30" + Task = "(L1) Ensure 'Special Administration Console Helper (sacsvr)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sacsvr" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.31" + Task = "(L1) Ensure 'SSDP Discovery (SSDPSRV)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SSDPSRV" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.32" + Task = "(L1) Ensure 'UPnP Device Host (upnphost)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\upnphost" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.33" + Task = "(L1) Ensure 'Web Management Service (WMSvc)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.34" + Task = "(L2) Ensure 'Windows Error Reporting Service (WerSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WerSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.35" + Task = "(L2) Ensure 'Windows Event Collector (Wecsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Wecsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.36" + Task = "(L1) Ensure 'Windows Media Player Network Sharing Service (WMPNetworkSvc)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMPNetworkSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.37" + Task = "(L1) Ensure 'Windows Mobile Hotspot Service (icssvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\icssvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.38" + Task = "(L2) Ensure 'Windows Push Notifications System Service (WpnService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WpnService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.39" + Task = "(L2) Ensure 'Windows PushToInstall Service (PushToInstall)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PushToInstall" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.40" + Task = "(L2) Ensure 'Windows Remote Management (WS-Management) (WinRM)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinRM" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.41" + Task = "(L1) Ensure 'World Wide Web Publishing Service (W3SVC)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.42" + Task = "(L1) Ensure 'Xbox Accessory Management Service (XboxGipSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxGipSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.43" + Task = "(L1) Ensure 'Xbox Live Auth Manager (XblAuthManager)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblAuthManager" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.44" + Task = "(L1) Ensure 'Xbox Live Game Save (XblGameSave)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblGameSave" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.45" + Task = "(L1) Ensure 'Xbox Live Networking Service (XboxNetApiSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxNetApiSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.1.1" + Task = "(L1) Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.2" + Task = "(L1) Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.3" + Task = "(L1) Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.4" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\domainfw.log'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SYSTEMROOT%\System32\logfiles\firewall\domainfw.log"; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.5" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.6" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.7" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.1" + Task = "(L1) Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.2" + Task = "(L1) Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.3" + Task = "(L1) Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.4" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\privatefw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\privatefw.log"; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.5" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.6" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.7" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.1" + Task = "(L1) Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.2" + Task = "(L1) Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.3" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.4" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.5" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.6" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\publicfw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\publicfw.log"; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.7" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.8" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.9" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "18.1.1.1" + Task = "(L1) Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.1.2" + Task = "(L1) Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.2.2" + Task = "(L1) Ensure 'Allow users to enable online speech recognition services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "AllowInputPersonalization" ` + | Select-Object -ExpandProperty "AllowInputPersonalization" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.3" + Task = "(L2) Ensure 'Allow Online Tips' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "AllowOnlineTips" ` + | Select-Object -ExpandProperty "AllowOnlineTips" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.1" + Task = "(L1) Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.2" + Task = "(L1) Ensure 'Configure RPC packet level privacy setting for incoming connections' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print" ` + -Name "RpcAuthnLevelPrivacyEnabled" ` + | Select-Object -ExpandProperty "RpcAuthnLevelPrivacyEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.3" + Task = "(L1) Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.4" + Task = "(L1) Ensure 'Configure SMB v1 server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.5" + Task = "(L1) Ensure 'Enable Certificate Padding' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Wintrust\Config" ` + -Name "EnableCertPaddingCheck" ` + | Select-Object -ExpandProperty "EnableCertPaddingCheck" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.6" + Task = "(L1) Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.7" + Task = "(L1) Ensure 'LSA Protection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RunAsPPL" ` + | Select-Object -ExpandProperty "RunAsPPL" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.8" + Task = "(L1) Ensure 'NetBT NodeType configuration' is set to 'Enabled: P-node (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.9" + Task = "(L1) Ensure 'WDigest Authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.1" + Task = "(L1) Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.2" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.3" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.4" + Task = "(L2) Ensure 'MSS: (DisableSavePassword) Prevent the dial-up password from being saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\RasMan\Parameters" ` + -Name "disablesavepassword" ` + | Select-Object -ExpandProperty "disablesavepassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.5" + Task = "(L1) Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.6" + Task = "(L2) Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "KeepAliveTime" ` + | Select-Object -ExpandProperty "KeepAliveTime" + + if ($regValue -ne 300000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 300000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.7" + Task = "(L1) Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.8" + Task = "(L2) Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "PerformRouterDiscovery" ` + | Select-Object -ExpandProperty "PerformRouterDiscovery" + + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.9" + Task = "(L1) Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.10" + Task = "(L1) Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires' is set to 'Enabled: 5 or fewer seconds'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScreenSaverGracePeriod" ` + | Select-Object -ExpandProperty "ScreenSaverGracePeriod" + + if ($regValue -notmatch "^[0-5]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[0-5]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.11" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.12" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.13" + Task = "(L1) Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security" ` + -Name "WarningLevel" ` + | Select-Object -ExpandProperty "WarningLevel" + + if (($regValue -gt 90)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 90" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.1" + Task = "(L1) Ensure 'Configure NetBIOS settings' is set to 2 - 'Enabled: Disable NetBIOS name resolution on public networks' (or 0 - Disable NetBIOS name resolution)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableNetBIOS" ` + | Select-Object -ExpandProperty "EnableNetBIOS" + + if (($regValue -ne 2) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.2" + Task = "(L1) Ensure 'Turn off multicast name resolution' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.5.1" + Task = "(L2) Ensure 'Enable Font Providers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableFontProviders" ` + | Select-Object -ExpandProperty "EnableFontProviders" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.1" + Task = "(L1) Ensure 'Enable insecure guest logons' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 A" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnDomain" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 B" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnPublicNet" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 C" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (EnableLLTDIO)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableLLTDIO" ` + | Select-Object -ExpandProperty "EnableLLTDIO" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 D" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitLLTDIOOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitLLTDIOOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 A" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnDomain" ` + | Select-Object -ExpandProperty "AllowRspndrOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 B" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnPublicNet" ` + | Select-Object -ExpandProperty "AllowRspndrOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 C" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (EnableRspndr)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableRspndr" ` + | Select-Object -ExpandProperty "EnableRspndr" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 D" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitRspndrOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitRspndrOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.10.2" + Task = "(L2) Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.2" + Task = "(L1) Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.3" + Task = "(L1) Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.4" + Task = "(L1) Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_StdDomainUserSetLocation" ` + | Select-Object -ExpandProperty "NC_StdDomainUserSetLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 A" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "RequirePrivacy=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 B" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "RequirePrivacy=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.19.2.1" + Task = "(L2) Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "DisabledComponents" ` + | Select-Object -ExpandProperty "DisabledComponents" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 A" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (EnableRegistrars)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "EnableRegistrars" ` + | Select-Object -ExpandProperty "EnableRegistrars" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 B" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableUPnPRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableUPnPRegistrar" ` + | Select-Object -ExpandProperty "DisableUPnPRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 C" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableInBand802DOT11Registrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableInBand802DOT11Registrar" ` + | Select-Object -ExpandProperty "DisableInBand802DOT11Registrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 D" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableFlashConfigRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableFlashConfigRegistrar" ` + | Select-Object -ExpandProperty "DisableFlashConfigRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 E" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableWPDRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableWPDRegistrar" ` + | Select-Object -ExpandProperty "DisableWPDRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.2" + Task = "(L2) Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI" ` + -Name "DisableWcnUi" ` + | Select-Object -ExpandProperty "DisableWcnUi" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.1" + Task = "(L1) Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled: 3 = Prevent Wi-Fi when on Ethernet'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fMinimizeConnections" ` + | Select-Object -ExpandProperty "fMinimizeConnections" + + if ($null -eq $regValue -or 0 -eq $regValue -or $regValue -gt 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1-3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.2" + Task = "(L1) Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.23.2.1" + Task = "(L1) Ensure 'Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config" ` + -Name "AutoConnectAllowedOEM" ` + | Select-Object -ExpandProperty "AutoConnectAllowedOEM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.1" + Task = "(L1) Ensure 'Allow Print Spooler to accept client connections' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "RegisterSpoolerRemoteRpcEndPoint" ` + | Select-Object -ExpandProperty "RegisterSpoolerRemoteRpcEndPoint" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.2" + Task = "(L1) Ensure 'Configure Redirection Guard' is set to 'Enabled: Redirection Guard Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "RedirectionGuardPolicy" ` + | Select-Object -ExpandProperty "RedirectionGuardPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.3" + Task = "(L1) Ensure 'Configure RPC connection settings: Protocol to use for outgoing RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcUseNamedPipeProtocol" ` + | Select-Object -ExpandProperty "RpcUseNamedPipeProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.4" + Task = "(L1) Ensure 'Configure RPC connection settings: Use authentication for outgoing RPC connections' is set to 'Enabled: Default'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcAuthentication" ` + | Select-Object -ExpandProperty "RpcAuthentication" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.5" + Task = "(L1) Ensure 'Configure RPC listener settings: Protocols to allow for incoming RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcProtocols" ` + | Select-Object -ExpandProperty "RpcProtocols" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.6" + Task = "(L1) Ensure 'Configure RPC listener settings: Authentication protocol to use for incoming RPC connections:' is set to 'Enabled: 0 - Negotiate' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "ForceKerberosForRpc" ` + | Select-Object -ExpandProperty "ForceKerberosForRpc" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0 or x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.7" + Task = "(L1) Ensure 'Configure RPC over TCP port' is set to 'Enabled: 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcTcpPort" ` + | Select-Object -ExpandProperty "RpcTcpPort" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.8" + Task = "(L1) Ensure 'Limits print driver installation to Administrators' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "RestrictDriverInstallationToAdministrators" ` + | Select-Object -ExpandProperty "RestrictDriverInstallationToAdministrators" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.9" + Task = "(L1) Ensure 'Manage processing of Queue-specific files' is set to 'Enabled: Limit Queue-specific files to Color profiles'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "CopyFilesPolicy" ` + | Select-Object -ExpandProperty "CopyFilesPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.10" + Task = "(L1) Ensure 'Point and Print Restrictions: When installing drivers for a new connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "NoWarningNoElevationOnInstall" ` + | Select-Object -ExpandProperty "NoWarningNoElevationOnInstall" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.11" + Task = "(L1) Ensure 'Point and Print Restrictions: When updating drivers for an existing connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "UpdatePromptSettings" ` + | Select-Object -ExpandProperty "UpdatePromptSettings" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.1.1" + Task = "(L2) Ensure 'Turn off notifications network usage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.3.1" + Task = "(L1) Ensure 'Include command line in process creation events' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.1" + Task = "(L1) Ensure 'Encryption Oracle Remediation' is set to 'Enabled: Force Updated Clients'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.2" + Task = "(L1) Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.1" + Task = "(NG) Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.2" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Select Platform Security Level' is set to 1 - 'Secure Boot' or 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if (($regValue -ne 1) -and ($regValue -ne 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.3" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Virtualization Based Protection of Code Integrity' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.4" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Require UEFI Memory Attributes Table' is set to 'True (checked)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HVCIMATRequired" ` + | Select-Object -ExpandProperty "HVCIMATRequired" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.5" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.6" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Secure Launch Configuration' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureSystemGuardLaunch" ` + | Select-Object -ExpandProperty "ConfigureSystemGuardLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.1" + Task = "(BL) Ensure 'Prevent installation of devices that match any of these device IDs' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceIDs" ` + | Select-Object -ExpandProperty "DenyDeviceIDs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.2" + Task = "(BL) Ensure 'Prevent installation of devices that match any of these device IDs: Prevent installation of devices that match any of these device IDs' is set to 'PCI\CC_0C0A'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceIDs" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "PCI\CC_0C0A") { + return @{ + Message = "Registry value is '$regValue'. Expected: PCI\CC_0C0A" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.3" + Task = "(BL) Ensure 'Prevent installation of devices that match any of these device IDs: Also apply to matching devices that are already installed.' is set to 'True' (checked)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceIDsRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceIDsRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.4" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClasses" ` + | Select-Object -ExpandProperty "DenyDeviceClasses" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.5 A" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the SBP2 Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "{d48179be-ec20-11d1-b6b8-00c04fa372a7}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {d48179be-ec20-11d1-b6b8-00c04fa372a7}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.5 B" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the IEC-61883 Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "2" ` + | Select-Object -ExpandProperty "2" + + if ($regValue -ne "{7ebefbc0-3200-11d2-b4c2-00a0C9697d07}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {7ebefbc0-3200-11d2-b4c2-00a0C9697d07}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.5 C" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the AVC Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "3" ` + | Select-Object -ExpandProperty "3" + + if ($regValue -ne "{c06ff265-ae09-48f0-812c-16753d7cba83}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {c06ff265-ae09-48f0-812c-16753d7cba83}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.5 D" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 Host Bus Controller Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "4" ` + | Select-Object -ExpandProperty "4" + + if ($regValue -ne "{6bdd1fc1-810f-11d0-bec7-08002be2092f}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {6bdd1fc1-810f-11d0-bec7-08002be2092f}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.6" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Also apply to matching devices that are already installed.' is set to 'True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClassesRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceClassesRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.2" + Task = "(L1) Ensure 'Prevent device metadata retrieval from the Internet' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" ` + -Name "PreventDeviceMetadataFromNetwork" ` + | Select-Object -ExpandProperty "PreventDeviceMetadataFromNetwork" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.13.1" + Task = "(L1) Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.2" + Task = "(L1) Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.3" + Task = "(L1) Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.4" + Task = "(L1) Ensure 'Configure security policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.5" + Task = "(L1) Ensure 'Configure security policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.6" + Task = "(L1) Ensure 'Continue experiences on this device' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableCdp" ` + | Select-Object -ExpandProperty "EnableCdp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.7" + Task = "(L1) Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableBkGndGroupPolicy" ` + | Select-Object -ExpandProperty "DisableBkGndGroupPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.1" + Task = "(L2) Ensure 'Turn off access to the Store' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoUseStoreOpenWith" ` + | Select-Object -ExpandProperty "NoUseStoreOpenWith" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.2" + Task = "(L1) Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.3" + Task = "(L2) Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC" ` + -Name "PreventHandwritingDataSharing" ` + | Select-Object -ExpandProperty "PreventHandwritingDataSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.4" + Task = "(L2) Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports" ` + -Name "PreventHandwritingErrorReports" ` + | Select-Object -ExpandProperty "PreventHandwritingErrorReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.5" + Task = "(L2) Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard" ` + -Name "ExitOnMSICW" ` + | Select-Object -ExpandProperty "ExitOnMSICW" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.6" + Task = "(L1) Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.7" + Task = "(L2) Ensure 'Turn off printing over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.8" + Task = "(L2) Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Registration Wizard Control" ` + -Name "NoRegistration" ` + | Select-Object -ExpandProperty "NoRegistration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.9" + Task = "(L2) Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion" ` + -Name "DisableContentFileUpdates" ` + | Select-Object -ExpandProperty "DisableContentFileUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.10" + Task = "(L2) Ensure 'Turn off the `"Order Prints`" picture task' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoOnlinePrintsWizard" ` + | Select-Object -ExpandProperty "NoOnlinePrintsWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.11" + Task = "(L2) Ensure 'Turn off the `"Publish to Web`" task for files and folders' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoPublishingWizard" ` + | Select-Object -ExpandProperty "NoPublishingWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.12" + Task = "(L2) Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client" ` + -Name "CEIP" ` + | Select-Object -ExpandProperty "CEIP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13" + Task = "(L2) Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows" ` + -Name "CEIPEnable" ` + | Select-Object -ExpandProperty "CEIPEnable" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.14 A" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (Disabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.14 B" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (DoReport)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting" ` + -Name "DoReport" ` + | Select-Object -ExpandProperty "DoReport" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 A" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitBehavior)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitBehavior" ` + | Select-Object -ExpandProperty "DevicePKInitBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 B" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitEnabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitEnabled" ` + | Select-Object -ExpandProperty "DevicePKInitEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.1" + Task = "(BL) Ensure 'Enumeration policy for external devices incompatible with Kernel DMA Protection' is set to 'Enabled: Block All'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.1" + Task = "(L1) Ensure 'Configure password backup directory' is set to 'Enabled: Active Directory' or 'Enabled: Azure Active Directory'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "BackupDirectory" ` + | Select-Object -ExpandProperty "BackupDirectory" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.2" + Task = "(L1) Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PwdExpirationProtectionEnabled" ` + | Select-Object -ExpandProperty "PwdExpirationProtectionEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.3" + Task = "(L1) Ensure 'Enable password encryption' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "ADPasswordEncryptionEnabled" ` + | Select-Object -ExpandProperty "ADPasswordEncryptionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.4" + Task = "(L1) Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordComplexity" ` + | Select-Object -ExpandProperty "PasswordComplexity" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.5" + Task = "(L1) Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordLength" ` + | Select-Object -ExpandProperty "PasswordLength" + + if (($regValue -lt 15)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.6" + Task = "(L1) Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordAgeDays" ` + | Select-Object -ExpandProperty "PasswordAgeDays" + + if (($regValue -gt 30 -or $regValue -lt 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30 and x >= 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.7" + Task = "(L1) Ensure 'Post-authentication actions: Grace period (hours)' is set to 'Enabled: 8 or fewer hours, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PostAuthenticationResetDelay" ` + | Select-Object -ExpandProperty "PostAuthenticationResetDelay" + + if (($regValue -gt 8 -or $regValue -le 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 8 and x > 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.8" + Task = "(L1) Ensure 'Post-authentication actions: Actions' is set to 3 - 'Enabled: Reset the password and logoff the managed account' or 5 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PostAuthenticationActions" ` + | Select-Object -ExpandProperty "PostAuthenticationActions" + + if (($regValue -ne 3) -and ($regValue -ne 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 3 or x == 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.1" + Task = "(L1) Ensure 'Allow Custom SSPs and APs to be loaded into LSASS' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowCustomSSPsAPs" ` + | Select-Object -ExpandProperty "AllowCustomSSPsAPs" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.2" + Task = "(NG) Ensure 'Configures LSASS to run as a protected process' is set to 'Enabled: Enabled with UEFI Lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "ConfigureLsaProtectedProcess" ` + | Select-Object -ExpandProperty "ConfigureLsaProtectedProcess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.1" + Task = "(L2) Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International" ` + -Name "BlockUserInputMethodsForSignIn" ` + | Select-Object -ExpandProperty "BlockUserInputMethodsForSignIn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.1" + Task = "(L1) Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockUserFromShowingAccountDetailsOnSignin" ` + | Select-Object -ExpandProperty "BlockUserFromShowingAccountDetailsOnSignin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.2" + Task = "(L1) Ensure 'Do not display network selection UI' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.3" + Task = "(L1) Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DontEnumerateConnectedUsers" ` + | Select-Object -ExpandProperty "DontEnumerateConnectedUsers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.4" + Task = "(L1) Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.5" + Task = "(L1) Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.6" + Task = "(L1) Ensure 'Turn off picture password sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockDomainPicturePassword" ` + | Select-Object -ExpandProperty "BlockDomainPicturePassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.7" + Task = "(L1) Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.31.1" + Task = "(L2) Ensure 'Allow Clipboard synchronization across devices' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowCrossDeviceClipboard" ` + | Select-Object -ExpandProperty "AllowCrossDeviceClipboard" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.31.2" + Task = "(L2) Ensure 'Allow upload of User Activities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "UploadUserActivities" ` + | Select-Object -ExpandProperty "UploadUserActivities" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.1" + Task = "(L1) Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.2" + Task = "(L1) Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.3" + Task = "(BL) Ensure 'Allow standby states (S1-S3) when sleeping (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.4" + Task = "(BL) Ensure 'Allow standby states (S1-S3) when sleeping (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.5" + Task = "(L1) Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.6" + Task = "(L1) Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.1" + Task = "(L1) Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.2" + Task = "(L1) Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.36.1" + Task = "(L1) Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" ` + -Name "EnableAuthEpResolution" ` + | Select-Object -ExpandProperty "EnableAuthEpResolution" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.36.2" + Task = "(L1) Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1" + Task = "(L2) Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.11.1" + Task = "(L2) Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d}" ` + -Name "ScenarioExecutionEnabled" ` + | Select-Object -ExpandProperty "ScenarioExecutionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.49.1" + Task = "(L2) Ensure 'Turn off the advertising ID' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" ` + -Name "DisabledByGroupPolicy" ` + | Select-Object -ExpandProperty "DisabledByGroupPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.51.1.1" + Task = "(L1) Ensure 'Enable Windows NTP Client' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.51.1.2" + Task = "(L1) Ensure 'Enable Windows NTP Server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.3.1" + Task = "(L2) Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager" ` + -Name "AllowSharedLocalAppData" ` + | Select-Object -ExpandProperty "AllowSharedLocalAppData" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.3.2" + Task = "(L1) Ensure 'Prevent non-admin users from installing packaged Windows apps' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Appx" ` + -Name "BlockNonAdminUserInstall" ` + | Select-Object -ExpandProperty "BlockNonAdminUserInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.4.1" + Task = "(L1) Ensure 'Let Windows apps activate with voice while the system is locked' is set to 'Enabled: Force Deny'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsActivateWithVoiceAboveLock" ` + | Select-Object -ExpandProperty "LetAppsActivateWithVoiceAboveLock" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.5.1" + Task = "(L1) Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.5.2" + Task = "(L2) Ensure 'Block launching Universal Windows apps with Windows Runtime API access from hosted content.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "BlockHostedAppAccessWinRT" ` + | Select-Object -ExpandProperty "BlockHostedAppAccessWinRT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.1" + Task = "(L1) Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.2" + Task = "(L1) Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.3" + Task = "(L1) Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.8.1.1" + Task = "(L1) Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.1" + Task = "(BL) Ensure 'Allow access to BitLocker-protected fixed data drives from earlier versions of Windows' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVDiscoveryVolumeType" ` + | Select-Object -ExpandProperty "FDVDiscoveryVolumeType" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: This value should be empty." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.2" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecovery" ` + | Select-Object -ExpandProperty "FDVRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Allow data recovery agent' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVManageDRA" ` + | Select-Object -ExpandProperty "FDVManageDRA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Recovery Password' is set to 'Enabled: Allow 48-digit recovery password' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecoveryPassword" ` + | Select-Object -ExpandProperty "FDVRecoveryPassword" + + if (($regValue -ne 2) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2 or 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Recovery Key' is set to 'Enabled: Allow 256-bit recovery key' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecoveryKey" ` + | Select-Object -ExpandProperty "FDVRecoveryKey" + + if (($regValue -ne 2) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2 or 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVHideRecoveryPage" ` + | Select-Object -ExpandProperty "FDVHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Save BitLocker recovery information to AD DS for fixed data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "FDVActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Configure storage of BitLocker recovery information to AD DS' is set to 'Enabled: Backup recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "FDVActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for fixed data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "FDVRequireActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.10" + Task = "(BL) Ensure 'Configure use of hardware-based encryption for fixed data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVHardwareEncryption" ` + | Select-Object -ExpandProperty "FDVHardwareEncryption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.11" + Task = "(BL) Ensure 'Configure use of passwords for fixed data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVPassphrase" ` + | Select-Object -ExpandProperty "FDVPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.12" + Task = "(BL) Ensure 'Configure use of smart cards on fixed data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVAllowUserCert" ` + | Select-Object -ExpandProperty "FDVAllowUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.13" + Task = "(BL) Ensure 'Configure use of smart cards on fixed data drives: Require use of smart cards on fixed data drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVEnforceUserCert" ` + | Select-Object -ExpandProperty "FDVEnforceUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.1" + Task = "(BL) Ensure 'Allow enhanced PINs for startup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseEnhancedPin" ` + | Select-Object -ExpandProperty "UseEnhancedPin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.2" + Task = "(BL) Ensure 'Allow Secure Boot for integrity validation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSAllowSecureBootForIntegrity" ` + | Select-Object -ExpandProperty "OSAllowSecureBootForIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecovery" ` + | Select-Object -ExpandProperty "OSRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Allow data recovery agent' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSManageDRA" ` + | Select-Object -ExpandProperty "OSManageDRA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Recovery Password' is set to 'Enabled: Require 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecoveryPassword" ` + | Select-Object -ExpandProperty "OSRecoveryPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Recovery Key' is set to 'Enabled: Do not allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecoveryKey" ` + | Select-Object -ExpandProperty "OSRecoveryKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSHideRecoveryPage" ` + | Select-Object -ExpandProperty "OSHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Save BitLocker recovery information to AD DS for operating system drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "OSActiveDirectoryBackup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Configure storage of BitLocker recovery information to AD DS:' is set to 'Enabled: Store recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "OSActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.10" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for operating system drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "OSRequireActiveDirectoryBackup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.11" + Task = "(BL) Ensure 'Configure use of hardware-based encryption for operating system drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSHardwareEncryption" ` + | Select-Object -ExpandProperty "OSHardwareEncryption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.12" + Task = "(BL) Ensure 'Configure use of passwords for operating system drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSPassphrase" ` + | Select-Object -ExpandProperty "OSPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.13" + Task = "(BL) Ensure 'Require additional authentication at startup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseAdvancedStartup" ` + | Select-Object -ExpandProperty "UseAdvancedStartup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.14" + Task = "(BL) Ensure 'Require additional authentication at startup: Allow BitLocker without a compatible TPM' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "EnableBDEWithNoTPM" ` + | Select-Object -ExpandProperty "EnableBDEWithNoTPM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.15" + Task = "(BL) Ensure 'Require additional authentication at startup: Configure TPM startup:' is set to 'Enabled: Do not allow TPM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPM" ` + | Select-Object -ExpandProperty "UseTPM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.16" + Task = "(BL) Ensure 'Require additional authentication at startup: Configure TPM startup PIN:' is set to 'Enabled: Require startup PIN with TPM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPMPIN" ` + | Select-Object -ExpandProperty "UseTPMPIN" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.17" + Task = "(BL) Ensure 'Require additional authentication at startup: Configure TPM startup key:' is set to 'Enabled: Do not allow startup key with TPM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPMKey" ` + | Select-Object -ExpandProperty "UseTPMKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.18" + Task = "(BL) Ensure 'Require additional authentication at startup: Configure TPM startup key and PIN:' is set to 'Enabled: Do not allow startup key and PIN with TPM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPMKeyPIN" ` + | Select-Object -ExpandProperty "UseTPMKeyPIN" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.1" + Task = "(BL) Ensure 'Allow access to BitLocker-protected removable data drives from earlier versions of Windows' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVDiscoveryVolumeType" ` + | Select-Object -ExpandProperty "RDVDiscoveryVolumeType" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: This value should be empty." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.2" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecovery" ` + | Select-Object -ExpandProperty "RDVRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Allow data recovery agent' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVManageDRA" ` + | Select-Object -ExpandProperty "RDVManageDRA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Recovery Password' is set to 'Enabled: Do not allow 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecoveryPassword" ` + | Select-Object -ExpandProperty "RDVRecoveryPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Recovery Key' is set to 'Enabled: Do not allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecoveryKey" ` + | Select-Object -ExpandProperty "RDVRecoveryKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVHideRecoveryPage" ` + | Select-Object -ExpandProperty "RDVHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Save BitLocker recovery information to AD DS for removable data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "RDVActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Configure storage of BitLocker recovery information to AD DS:' is set to 'Enabled: Backup recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "RDVActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for removable data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "RDVRequireActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.10" + Task = "(BL) Ensure 'Configure use of hardware-based encryption for removable data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVHardwareEncryption" ` + | Select-Object -ExpandProperty "RDVHardwareEncryption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.11" + Task = "(BL) Ensure 'Configure use of passwords for removable data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVPassphrase" ` + | Select-Object -ExpandProperty "RDVPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.12" + Task = "(BL) Ensure 'Configure use of smart cards on removable data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVAllowUserCert" ` + | Select-Object -ExpandProperty "RDVAllowUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.13" + Task = "(BL) Ensure 'Configure use of smart cards on removable data drives: Require use of smart cards on removable data drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVEnforceUserCert" ` + | Select-Object -ExpandProperty "RDVEnforceUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.14" + Task = "(BL) Ensure 'Deny write access to removable drives not protected by BitLocker' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\Microsoft\FVE" ` + -Name "RDVDenyWriteAccess" ` + | Select-Object -ExpandProperty "RDVDenyWriteAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.15" + Task = "(BL) Ensure 'Deny write access to removable drives not protected by BitLocker: Do not allow write access to devices configured in another organization' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVDenyCrossOrg" ` + | Select-Object -ExpandProperty "RDVDenyCrossOrg" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.4" + Task = "(BL) Ensure 'Disable new DMA devices when this computer is locked' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "DisableExternalDMAUnderLock" ` + | Select-Object -ExpandProperty "DisableExternalDMAUnderLock" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1" + Task = "(L2) Ensure 'Allow Use of Camera' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera" ` + -Name "AllowCamera" ` + | Select-Object -ExpandProperty "AllowCamera" + + if ($regValue -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam" ` + -Name "Value" ` + | Select-Object -ExpandProperty "Value" + + if ($regValue -match "Deny") { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Camera is not deactivated." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "18.10.12.1" + Task = "(L1) Ensure 'Turn off cloud consumer account state content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableConsumerAccountStateContent" ` + | Select-Object -ExpandProperty "DisableConsumerAccountStateContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.12.2" + Task = "(L2) Ensure 'Turn off cloud optimized content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableCloudOptimizedContent" ` + | Select-Object -ExpandProperty "DisableCloudOptimizedContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.12.3" + Task = "(L1) Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.13.1" + Task = "(L1) Ensure 'Require pin for pairing' is set to 'Enabled: First Time' OR 'Enabled: Always'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect" ` + -Name "RequirePinForPairing" ` + | Select-Object -ExpandProperty "RequirePinForPairing" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.1" + Task = "(L1) Ensure 'Do not display the password reveal button' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.2" + Task = "(L1) Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.3" + Task = "(L1) Ensure 'Prevent the use of security questions for local accounts' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "NoLocalPasswordResetQuestions" ` + | Select-Object -ExpandProperty "NoLocalPasswordResetQuestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.1" + Task = "(L1) Ensure 'Allow Diagnostic Data' is set to '0 - Enabled: Diagnostic data off (not recommended)' or '1 - Enabled: Send required diagnostic data'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0 or x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.2" + Task = "(L2) Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableEnterpriseAuthProxy" ` + | Select-Object -ExpandProperty "DisableEnterpriseAuthProxy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.3" + Task = "(L1) Ensure 'Disable OneSettings Downloads' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableOneSettingsDownloads" ` + | Select-Object -ExpandProperty "DisableOneSettingsDownloads" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.4" + Task = "(L1) Ensure 'Do not show feedback notifications' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DoNotShowFeedbackNotifications" ` + | Select-Object -ExpandProperty "DoNotShowFeedbackNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.5" + Task = "(L1) Ensure 'Enable OneSettings Auditing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "EnableOneSettingsAuditing" ` + | Select-Object -ExpandProperty "EnableOneSettingsAuditing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.6" + Task = "(L1) Ensure 'Limit Diagnostic Log Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDiagnosticLogCollection" ` + | Select-Object -ExpandProperty "LimitDiagnosticLogCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.7" + Task = "(L1) Ensure 'Limit Dump Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDumpCollection" ` + | Select-Object -ExpandProperty "LimitDumpCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.8" + Task = "(L1) Ensure 'Toggle user control over Insider builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" ` + -Name "AllowBuildPreview" ` + | Select-Object -ExpandProperty "AllowBuildPreview" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.1" + Task = "(L1) Ensure 'Download Mode' is NOT set to 3 - 'Enabled: Internet'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization" ` + -Name "DODownloadMode" ` + | Select-Object -ExpandProperty "DODownloadMode" + + if ($regValue -notmatch "^(0|1|2|99|100)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(0|1|2|99|100)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.1" + Task = "(L1) Ensure 'Enable App Installer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableAppInstaller" ` + | Select-Object -ExpandProperty "EnableAppInstaller" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.2" + Task = "(L1) Ensure 'Enable App Installer Experimental Features' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableExperimentalFeatures" ` + | Select-Object -ExpandProperty "EnableExperimentalFeatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.3" + Task = "(L1) Ensure 'Enable App Installer Hash Override' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableHashOverride" ` + | Select-Object -ExpandProperty "EnableHashOverride" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.4" + Task = "(L1) Ensure 'Enable App Installer ms-appinstaller protocol' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableMSAppInstallerProtocol" ` + | Select-Object -ExpandProperty "EnableMSAppInstallerProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.1.1" + Task = "(L1) Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.1.2" + Task = "(L1) Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.2.1" + Task = "(L1) Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.2.2" + Task = "(L1) Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 196608)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.3.1" + Task = "(L1) Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.3.2" + Task = "(L1) Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.4.1" + Task = "(L1) Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.4.2" + Task = "(L1) Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.28.2" + Task = "(L1) Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.28.3" + Task = "(L1) Ensure 'Turn off heap termination on corruption' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.28.4" + Task = "(L1) Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.34.1" + Task = "(L1) Ensure 'Disable Internet Explorer 11 as a standalone browser' is set to 'Enabled: Always'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Main" ` + -Name "NotifyDisableIEOptions" ` + | Select-Object -ExpandProperty "NotifyDisableIEOptions" + + $idMapping = @{ + 0 = "Don't notify" + 1 = "Always notify" + 2 = "Notify once" + } + return @{ + Message = "Compliant. Following setting is set: " + $idMapping[$regValue] + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.36.1" + Task = "(L2) Ensure 'Turn off location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.40.1" + Task = "(L2) Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging" ` + -Name "AllowMessageSync" ` + | Select-Object -ExpandProperty "AllowMessageSync" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.41.1" + Task = "(L1) Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount" ` + -Name "DisableUserAuth" ` + | Select-Object -ExpandProperty "DisableUserAuth" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.5.1" + Task = "(L1) Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.5.2" + Task = "(L2) Ensure 'Join Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.1" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 A" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office communication application from creating child processes'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 B" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating executable content'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 C" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block abuse of exploited vulnerable signed drivers'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 D" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block execution of potentially obfuscated scripts'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 E" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from injecting code into other processes'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 F" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Adobe Reader from creating child processes'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 G" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Win32 API calls from Office macro'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 H" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block credential stealing from the Windows local security authority subsystem (lsass.exe)'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 I" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block untrusted and unsigned processes that run from USB'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 J" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block executable content from email client and webmail'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 K" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block JavaScript or VBScript from launching downloaded executable content'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 L" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating child processes'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 M" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block persistence through WMI event subscription'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.3.1" + Task = "(L1) Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.7.1" + Task = "(L1) Ensure 'Enable file hash computation feature' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine" ` + -Name "EnableFileHashComputation" ` + | Select-Object -ExpandProperty "EnableFileHashComputation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.1" + Task = "(L1) Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.2" + Task = "(L1) Ensure 'Turn off real-time protection' is set to 'Disabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.3" + Task = "(L1) Ensure 'Turn on behavior monitoring' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.4" + Task = "(L1) Ensure 'Turn on script scanning' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableScriptScanning" ` + | Select-Object -ExpandProperty "DisableScriptScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.12.1" + Task = "(L2) Ensure 'Configure Watson events' is set to 'Disabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" ` + -Name "DisableGenericReports" ` + | Select-Object -ExpandProperty "DisableGenericReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.13.1" + Task = "(L1) Ensure 'Scan packed executables' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisablePackedExeScanning" ` + | Select-Object -ExpandProperty "DisablePackedExeScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.13.2" + Task = "(L1) Ensure 'Scan removable drives' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.13.3" + Task = "(L1) Ensure 'Turn on e-mail scanning' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.16" + Task = "(L1) Ensure 'Configure detection for potentially unwanted applications' is set to 'Enabled: Block'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.17" + Task = "(L1) Ensure 'Turn off Microsoft Defender AntiVirus' is set to 'Disabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "DisableAntiSpyware" ` + | Select-Object -ExpandProperty "DisableAntiSpyware" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.1" + Task = "(NG) Ensure 'Allow auditing events in Microsoft Defender Application Guard' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AuditApplicationGuard" ` + | Select-Object -ExpandProperty "AuditApplicationGuard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.2" + Task = "(NG) Ensure 'Allow camera and microphone access in Microsoft Defender Application Guard' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowCameraMicrophoneRedirection" ` + | Select-Object -ExpandProperty "AllowCameraMicrophoneRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.3" + Task = "(NG) Ensure 'Allow data persistence for Microsoft Defender Application Guard' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowPersistence" ` + | Select-Object -ExpandProperty "AllowPersistence" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.4" + Task = "(NG) Ensure 'Allow files to download and save to the host operating system from Microsoft Defender Application Guard' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "SaveFilesToHost" ` + | Select-Object -ExpandProperty "SaveFilesToHost" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.5" + Task = "(NG) Ensure 'Configure Microsoft Defender Application Guard clipboard settings: Clipboard behavior setting' is set to 'Enabled: Enable clipboard operation from an isolated session to the host'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AppHVSIClipboardSettings" ` + | Select-Object -ExpandProperty "AppHVSIClipboardSettings" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6" + Task = "(NG) Ensure 'Turn on Microsoft Defender Application Guard in Managed Mode' is set to 'Enabled: 1'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowAppHVSI_ProviderSet" ` + | Select-Object -ExpandProperty "AllowAppHVSI_ProviderSet" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.49.1" + Task = "(L2) Ensure 'Enable news and interests on the taskbar' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Feeds" ` + -Name "EnableFeeds" ` + | Select-Object -ExpandProperty "EnableFeeds" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.50.1" + Task = "(L1) Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.55.1" + Task = "(L2) Ensure 'Turn off Push To Install service' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall" ` + -Name "DisablePushToInstall" ` + | Select-Object -ExpandProperty "DisablePushToInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.2.2" + Task = "(L1) Ensure 'Do not allow passwords to be saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.2.1" + Task = "(L2) Ensure 'Allow users to connect remotely by using Remote Desktop Services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDenyTSConnections" ` + | Select-Object -ExpandProperty "fDenyTSConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.1" + Task = "(L2) Ensure 'Allow UI Automation redirection' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "EnableUiaRedirection" ` + | Select-Object -ExpandProperty "EnableUiaRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.2" + Task = "(L2) Ensure 'Do not allow COM port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCcm" ` + | Select-Object -ExpandProperty "fDisableCcm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.3" + Task = "(L1) Ensure 'Do not allow drive redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.4" + Task = "(L2) Ensure 'Do not allow location redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLocationRedir" ` + | Select-Object -ExpandProperty "fDisableLocationRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.5" + Task = "(L2) Ensure 'Do not allow LPT port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLPT" ` + | Select-Object -ExpandProperty "fDisableLPT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.6" + Task = "(L2) Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisablePNPRedir" ` + | Select-Object -ExpandProperty "fDisablePNPRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.7" + Task = "(L2) Ensure 'Do not allow WebAuthn redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableWebAuthn" ` + | Select-Object -ExpandProperty "fDisableWebAuthn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.1" + Task = "(L1) Ensure 'Always prompt for password upon connection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.2" + Task = "(L1) Ensure 'Require secure RPC communication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.3" + Task = "(L1) Ensure 'Require use of specific security layer for remote (RDP) connections' is set to 'Enabled: SSL'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SecurityLayer" ` + | Select-Object -ExpandProperty "SecurityLayer" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.4" + Task = "(L1) Ensure 'Require user authentication for remote connections by using Network Level Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "UserAuthentication" ` + | Select-Object -ExpandProperty "UserAuthentication" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.5" + Task = "(L1) Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.10.1" + Task = "(L2) Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less, but not Never (0)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxIdleTime" ` + | Select-Object -ExpandProperty "MaxIdleTime" + + if (($regValue -gt 900000 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900000 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.10.2" + Task = "(L2) Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxDisconnectionTime" ` + | Select-Object -ExpandProperty "MaxDisconnectionTime" + + if ($regValue -ne 60000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 60000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.11.1" + Task = "(L1) Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.1" + Task = "(L1) Ensure 'Prevent downloading of enclosures' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.2" + Task = "(L2) Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCloudSearch" ` + | Select-Object -ExpandProperty "AllowCloudSearch" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.3" + Task = "(L1) Ensure 'Allow Cortana' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCortana" ` + | Select-Object -ExpandProperty "AllowCortana" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.4" + Task = "(L1) Ensure 'Allow Cortana above lock screen' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCortanaAboveLock" ` + | Select-Object -ExpandProperty "AllowCortanaAboveLock" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.5" + Task = "(L1) Ensure 'Allow indexing of encrypted files' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.6" + Task = "(L1) Ensure 'Allow search and Cortana to use location' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowSearchToUseLocation" ` + | Select-Object -ExpandProperty "AllowSearchToUseLocation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.7" + Task = "(L2) Ensure 'Allow search highlights' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "EnableDynamicContentInWSB" ` + | Select-Object -ExpandProperty "EnableDynamicContentInWSB" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.62.1" + Task = "(L2) Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" ` + -Name "NoGenTicket" ` + | Select-Object -ExpandProperty "NoGenTicket" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.65.1" + Task = "(L2) Ensure 'Disable all apps from Microsoft Store' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "DisableStoreApps" ` + | Select-Object -ExpandProperty "DisableStoreApps" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.65.2" + Task = "(L1) Ensure 'Only display the private store within the Microsoft Store' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "RequirePrivateStoreOnly" ` + | Select-Object -ExpandProperty "RequirePrivateStoreOnly" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.65.3" + Task = "(L1) Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "AutoDownload" ` + | Select-Object -ExpandProperty "AutoDownload" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.65.4" + Task = "(L1) Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "DisableOSUpgrade" ` + | Select-Object -ExpandProperty "DisableOSUpgrade" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.65.5" + Task = "(L2) Ensure 'Turn off the Store application' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "RemoveWindowsStore" ` + | Select-Object -ExpandProperty "RemoveWindowsStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.71.1" + Task = "(L1) Ensure 'Allow widgets' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Dsh" ` + -Name "AllowNewsAndInterests" ` + | Select-Object -ExpandProperty "AllowNewsAndInterests" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.75.2.1 A" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (EnableSmartScreen)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.75.2.1 B" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (ShellSmartScreenLevel)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.77.1" + Task = "(L1) Ensure 'Enables or disables Windows Game Recording and Broadcasting' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR" ` + -Name "AllowGameDVR" ` + | Select-Object -ExpandProperty "AllowGameDVR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.79.1" + Task = "(L2) Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowSuggestedAppsInWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowSuggestedAppsInWindowsInkWorkspace" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.79.2" + Task = "(L1) Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Enabled: Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if (($regValue -ne 1) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.1" + Task = "(L1) Ensure 'Allow user control over installs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.2" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.3" + Task = "(L2) Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.1" + Task = "(L1) Ensure 'Enable MPR notifications for the system' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableMPR" ` + | Select-Object -ExpandProperty "EnableMPR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.2" + Task = "(L1) Ensure 'Sign-in and lock last interactive user automatically after a restart' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.86.1" + Task = "(L2) Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.86.2" + Task = "(L2) Ensure 'Turn on PowerShell Transcription' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" ` + -Name "EnableTranscripting" ` + | Select-Object -ExpandProperty "EnableTranscripting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.1.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.1.2" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.1.3" + Task = "(L1) Ensure 'Disallow Digest authentication' is set to 'Enabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.2" + Task = "(L2) Ensure 'Allow remote server management through WinRM' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowAutoConfig" ` + | Select-Object -ExpandProperty "AllowAutoConfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.3" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.4" + Task = "(L1) Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1" + Task = "(L2) Ensure 'Allow Remote Shell Access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS" ` + -Name "AllowRemoteShellAccess" ` + | Select-Object -ExpandProperty "AllowRemoteShellAccess" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.90.1" + Task = "(L1) Ensure 'Allow clipboard sharing with Windows Sandbox' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Sandbox" ` + -Name "AllowClipboardRedirection" ` + | Select-Object -ExpandProperty "AllowClipboardRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.90.2" + Task = "(L1) Ensure 'Allow networking in Windows Sandbox' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Sandbox" ` + -Name "AllowNetworking" ` + | Select-Object -ExpandProperty "AllowNetworking" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.91.2.1" + Task = "(L1) Ensure 'Prevent users from modifying settings' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection" ` + -Name "DisallowExploitProtectionOverride" ` + | Select-Object -ExpandProperty "DisallowExploitProtectionOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.1.1" + Task = "(L1) Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.1" + Task = "(L1) Ensure 'Configure Automatic Updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.2" + Task = "(L1) Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.3" + Task = "(L1) Ensure 'Remove access to `"Pause updates`" feature' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "SetDisablePauseUXAccess" ` + | Select-Object -ExpandProperty "SetDisablePauseUXAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.1" + Task = "(L1) Ensure 'Manage preview builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "ManagePreviewBuildsPolicyValue" ` + | Select-Object -ExpandProperty "ManagePreviewBuildsPolicyValue" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.2 A" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdates" ` + | Select-Object -ExpandProperty "DeferFeatureUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.2 B" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferFeatureUpdatesPeriodInDays" + + if (($regValue -lt 180 -or $regValue -gt 365)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 180 and x <= 365" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.3 A" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdates" ` + | Select-Object -ExpandProperty "DeferQualityUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.3 B" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferQualityUpdatesPeriodInDays" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.5.1.1" + Task = "(L1) Ensure 'Turn off toast notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.6.6.1.1" + Task = "(L2) Ensure 'Turn off Help Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Assistance\Client\1.0" ` + -Name "NoImplicitFeedback" ` + | Select-Object -ExpandProperty "NoImplicitFeedback" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.5.1" + Task = "(L1) Ensure 'Do not preserve zone information in file attachments' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.5.2" + Task = "(L1) Ensure 'Notify antivirus programs when opening attachments' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "ScanWithAntiVirus" ` + | Select-Object -ExpandProperty "ScanWithAntiVirus" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.1" + Task = "(L1) Ensure 'Configure Windows spotlight on lock screen' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "ConfigureWindowsSpotlight" ` + | Select-Object -ExpandProperty "ConfigureWindowsSpotlight" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.2" + Task = "(L1) Ensure 'Do not suggest third-party content in Windows spotlight' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.3" + Task = "(L2) Ensure 'Do not use diagnostic data for tailored experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableTailoredExperiencesWithDiagnosticData" ` + | Select-Object -ExpandProperty "DisableTailoredExperiencesWithDiagnosticData" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.4" + Task = "(L2) Ensure 'Turn off all Windows spotlight features' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsSpotlightFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsSpotlightFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.5" + Task = "(L1) Ensure 'Turn off Spotlight collection on Desktop' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableSpotlightCollectionOnDesktop" ` + | Select-Object -ExpandProperty "DisableSpotlightCollectionOnDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.26.1" + Task = "(L1) Ensure 'Prevent users from sharing files within their profile.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInplaceSharing" ` + | Select-Object -ExpandProperty "NoInplaceSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.42.1" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled' (AlwaysInstallElevated)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.44.2.1" + Task = "(L2) Ensure 'Prevent Codec Download' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer" ` + -Name "PreventCodecDownload" ` + | Select-Object -ExpandProperty "PreventCodecDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} \ No newline at end of file diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#SecurityOptions.ps1 new file mode 100644 index 0000000..0cd9c29 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#SecurityOptions.ps1 @@ -0,0 +1,130 @@ +[AuditTest] @{ + Id = "2.3.1.2" + Task = "(L1) Ensure 'Accounts: Guest account status' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.4" + Task = "(L1) Configure 'Accounts: Rename administrator account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption. Expected: ^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.5" + Task = "(L1) Configure 'Accounts: Rename guest account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption. Expected: ^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.1" + Task = "(L1) Ensure 'Network access: Allow anonymous SID/Name translation' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.6" + Task = "(L1) Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["ForceLogoffWhenHourExpire"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 1) { + return @{ + Message = "'ForceLogoffWhenHourExpire' currently set to: $setOption. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} \ No newline at end of file diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#UserRights.ps1 new file mode 100644 index 0000000..cfee1ad --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-CIS-3.0.0#UserRights.ps1 @@ -0,0 +1,1488 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "2.2.1" + Task = "(L1) Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Remote Desktop Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.3" + Task = "(L1) Ensure 'Act as part of the operating system' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.4" + Task = "(L1) Ensure 'Adjust memory quotas for a process' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseQuotaPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseQuotaPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseQuotaPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.5" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.6" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators, Remote Desktop Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.7" + Task = "(L1) Ensure 'Back up files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.8" + Task = "(L1) Ensure 'Change the system time' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemtimePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemtimePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemtimePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.9" + Task = "(L1) Ensure 'Change the time zone' is set to 'Administrators, LOCAL SERVICE, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTimeZonePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTimeZonePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTimeZonePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.10" + Task = "(L1) Ensure 'Create a pagefile' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.11" + Task = "(L1) Ensure 'Create a token object' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.12" + Task = "(L1) Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.13" + Task = "(L1) Ensure 'Create permanent shared objects' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if($hyperVStatus -ne "Enabled"){ + [AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Configure 'Create symbolic links' [Hyper-V-Feature NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else{ + [AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Configure 'Create symbolic links' [Hyper-V-Feature installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.15" + Task = "(L1) Ensure 'Debug programs' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.16" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests, Local account'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-113" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.17" + Task = "(L1) Ensure 'Deny log on as a batch job' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.18" + Task = "(L1) Ensure 'Deny log on as a service' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyServiceLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Deny log on locally' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.20" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' to include 'Guests, Local account'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-113" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.21" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.22" + Task = "(L1) Ensure 'Force shutdown from a remote system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.23" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.24" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-6" + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.25" + Task = "(L1) Ensure 'Increase scheduling priority' is set to 'Administrators, Window Manager\Window Manager Group'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseBasePriorityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-90-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseBasePriorityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseBasePriorityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.26" + Task = "(L1) Ensure 'Load and unload device drivers' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.27" + Task = "(L1) Ensure 'Lock pages in memory' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.28" + Task = "(L2) Ensure 'Log on as a batch job' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBatchLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if($hyperVStatus -ne "Enabled"){ + [AuditTest] @{ + Id = "2.2.29" + Task = "(L2) Configure 'Log on as a service' [Hyper-V-Feature NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeServiceLogonRight"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeServiceLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else{ + [AuditTest] @{ + Id = "2.2.29" + Task = "(L2) Configure 'Log on as a service' [Hyper-V-Feature installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeServiceLogonRight"] + $identityAccounts = @( + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeServiceLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.30" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.31" + Task = "(L1) Ensure 'Modify an object label' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRelabelPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRelabelPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRelabelPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.32" + Task = "(L1) Ensure 'Modify firmware environment values' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.33" + Task = "(L1) Ensure 'Perform volume maintenance tasks' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.34" + Task = "(L1) Ensure 'Profile single process' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.35" + Task = "(L1) Ensure 'Profile system performance' is set to 'Administrators, NT SERVICE\WdiServiceHost'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemProfilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemProfilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemProfilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.36" + Task = "(L1) Ensure 'Replace a process level token' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAssignPrimaryTokenPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAssignPrimaryTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAssignPrimaryTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.37" + Task = "(L1) Ensure 'Restore files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.38" + Task = "(L1) Ensure 'Shut down the system' is set to 'Administrators, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.39" + Task = "(L1) Ensure 'Take ownership of files or other objects' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#AccountPolicies.ps1 new file mode 100644 index 0000000..ba3fa09 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#AccountPolicies.ps1 @@ -0,0 +1,252 @@ +[AuditTest] @{ + Id = "V-63405" + Task = "Windows 10 account lockout duration must be configured to 15 minutes or greater." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15) -and ($setPolicy -ne 0)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15 or x == 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63409" + Task = "The number of allowed bad logon attempts must be configured to 3 or less." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 3 -or $setPolicy -eq 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x >= 3 and x != 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63413" + Task = "The period of time before the bad logon counter is reset must be configured to 15 minutes." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63415" + Task = "The password history must be configured to 24 passwords remembered." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63419" + Task = "The maximum password age must be configured to 60 days or less." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 60 -or $setPolicy -eq 0)) { + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 60 and x != 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63421" + Task = "The minimum password age must be configured to at least 1 day." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 1)) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63423" + Task = "Passwords must, at a minimum, be 14 characters." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63427" + Task = "The built-in Microsoft password complexity filter must be enabled." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63429" + Task = "Reversible password encryption must be disabled." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#AuditPolicies.ps1 new file mode 100644 index 0000000..d326eb9 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#AuditPolicies.ps1 @@ -0,0 +1,1559 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "V-63431 + V-63435" + Task = "The system must be configured to audit Account Logon - Credential Validation failures. The system must be configured to audit Account Logon - Credential Validation successes." + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63445" + Task = "The system must be configured to audit Account Management - Security Group Management successes." + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63447 + V-63449" + Task = "The system must be configured to audit Account Management - User Account Management failures. The system must be configured to audit Account Management - User Account Management successes." + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63451" + Task = "The system must be configured to audit Detailed Tracking - PNP Activity successes." + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63453" + Task = "The system must be configured to audit Detailed Tracking - Process Creation successes." + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63457" + Task = "The system must be configured to audit Logon/Logoff - Group Membership successes." + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63459" + Task = "The system must be configured to audit Logon/Logoff - Logoff successes." + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63463 + V-63467" + Task = "The system must be configured to audit Logon/Logoff - Logon failures. The system must be configured to audit Logon/Logoff - Logon successes." + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63469" + Task = "The system must be configured to audit Logon/Logoff - Special Logon successes." + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63471 + V-63473" + Task = "The system must be configured to audit Object Access - Removable Storage failures. The system must be configured to audit Object Access - Removable Storage successes." + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63479" + Task = "The system must be configured to audit Policy Change - Audit Policy Change successes." + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63481" + Task = "The system must be configured to audit Policy Change - Authentication Policy Change successes." + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63483 + V-63487" + Task = "The system must be configured to audit Privilege Use - Sensitive Privilege Use failures. The system must be configured to audit Privilege Use - Sensitive Privilege Use successes." + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63491" + Task = "The system must be configured to audit System - IPSec Driver failures." + Test = { + # Get the audit policy for the subcategory IPSec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "IPSec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'IPSec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63499 + V-63503" + Task = "The system must be configured to audit System - Other System Events successes. The system must be configured to audit System - Other System Events failures." + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63507" + Task = "The system must be configured to audit System - Security State Change successes." + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63513" + Task = "The system must be configured to audit System - Security System Extension successes." + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63515 + V-63517" + Task = "The system must be configured to audit System - System Integrity failures. The system must be configured to audit System - System Integrity successes." + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-71759" + Task = "The system must be configured to audit Logon/Logoff - Account Lockout failures." + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-71761" + Task = "The system must be configured to audit Policy Change - Authorization Policy Change successes." + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-74409 + V-74411" + Task = "Windows 10 must be configured to audit Object Access - Other Object Access Events failures. Windows 10 must be configured to audit Object Access - Other Object Access Events successes." + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-74721 + V-75027" + Task = "Windows 10 must be configured to audit Object Access - File Share successes. Windows 10 must be configured to audit Object Access - File Share failures." + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-99541 + V-99543" + Task = "Windows 10 must be configured to audit other Logon/Logoff Events Failures. Windows 10 must be configured to audit other Logon/Logoff Events Successes." + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-99545" + Task = "Windows 10 must be configured to audit Detailed File Share Failures." + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-99547 + V-99549" + Task = "Windows 10 must be configured to audit MPSSVC Rule-Level Policy Change Successes. Windows 10 must be configured to audit MPSSVC Rule-Level Policy Change Failures." + Test = { + # Get the audit policy for the subcategory MPSSVC Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "MPSSVC Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'MPSSVC Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-99551 + V-99553" + Task = "Windows 10 must be configured to audit Other Policy Change Events Successes. Windows 10 must be configured to audit Other Policy Change Events Failures." + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#RegistrySettings.ps1 new file mode 100644 index 0000000..d20d84c --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#RegistrySettings.ps1 @@ -0,0 +1,4142 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +[AuditTest] @{ + Id = "V-63321" + Task = "Users must be prevented from changing installation options." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63325" + Task = "The Windows Installer Always install with elevated privileges must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63329" + Task = "Users must be notified if a web-based program attempts to install software." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63333" + Task = "Automatically signing in the last interactive user after a system-initiated restart must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63335" + Task = "The Windows Remote Management (WinRM) client must not use Basic authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63339" + Task = "The Windows Remote Management (WinRM) client must not allow unencrypted traffic." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63341" + Task = "The Windows Remote Management (WinRM) client must not use Digest authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63347" + Task = "The Windows Remote Management (WinRM) service must not use Basic authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63369" + Task = "The Windows Remote Management (WinRM) service must not allow unencrypted traffic." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63375" + Task = "The Windows Remote Management (WinRM) service must not store RunAs credentials." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63519" + Task = "The Application event log size must be configured to 32768 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63523" + Task = "The Security event log size must be configured to 1024000 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 1024000) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 1024000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63527" + Task = "The System event log size must be configured to 32768 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63545" + Task = "Camera access from the lock screen must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63549" + Task = "The display of slide shows on the lock screen must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63555" + Task = "IPv6 source routing must be configured to highest protection." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIpSourceRouting" ` + | Select-Object -ExpandProperty "DisableIpSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63559" + Task = "The system must be configured to prevent IP source routing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63563" + Task = "The system must be configured to prevent Internet Control Message Protocol (ICMP) redirects from overriding Open Shortest Path First (OSPF) generated routes." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63567" + Task = "The system must be configured to ignore NetBIOS name release requests except from WINS servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NoNameReleaseOnDemand" ` + | Select-Object -ExpandProperty "NoNameReleaseOnDemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63569" + Task = "Insecure logons to an SMB server must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63581" + Task = "Simultaneous connections to the Internet or a Windows domain must be limited." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fMinimizeConnections" ` + | Select-Object -ExpandProperty "fMinimizeConnections" + + if ($null -eq $regValue -or 0 -eq $regValue) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1-3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63585" + Task = "Connections to non-domain networks when connected to a domain authenticated network must be blocked." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($null -eq $regValue -or 0 -eq $regValue) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1-3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63591" + Task = "Wi-Fi Sense must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config" ` + -Name "AutoConnectAllowedOEM" ` + | Select-Object -ExpandProperty "AutoConnectAllowedOEM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63597" + Task = "Local administrator accounts must have their privileged token filtered to prevent elevated privileges from being used over the network on domain systems." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63607" + Task = "Early Launch Antimalware, Boot-Start Driver Initialization Policy must prevent boot drivers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if (($regValue -ne 1) -and ($regValue -ne 3) -and ($regValue -ne 8)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 3 or x == 8" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63609" + Task = "Group Policy objects must be reprocessed even if they have not changed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63615" + Task = "Downloading print driver packages over HTTP must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63617" + Task = "Local accounts with blank passwords must be restricted to prevent access from the network." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63621" + Task = "Web publishing and online ordering wizards must be prevented from downloading a list of providers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63623" + Task = "Printing over HTTP must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63627" + Task = "Systems must at least attempt device authentication using certificates." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "DevicePKInitEnabled" ` + | Select-Object -ExpandProperty "DevicePKInitEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63629" + Task = "The network selection user interface (UI) must not be displayed on the logon screen." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63633" + Task = "Local users on domain-joined computers must not be enumerated." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63635" + Task = "Audit policy using subcategories must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63639" + Task = "Outgoing secure channel traffic must be encrypted or signed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63643" + Task = "Outgoing secure channel traffic must be encrypted when possible." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63645" + Task = "Users must be prompted for a password on resume from sleep (on battery)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63647" + Task = "Outgoing secure channel traffic must be signed when possible." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63649" + Task = "The user must be prompted for a password on resume from sleep (plugged in)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63651" + Task = "Solicited Remote Assistance must not be allowed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63653" + Task = "The computer account password must not be prevented from being reset." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63657" + Task = "Unauthenticated RPC clients must be restricted from connecting to the RPC server." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63659" + Task = "The setting to allow Microsoft accounts to be optional for modern style apps must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63661" + Task = "The maximum age for machine account passwords must be configured to 30 days or less." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if (($regValue -gt 30 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63663 A" + Task = "The Application Compatibility Program service must be disabled in order to prefent sending inventory data." + Test = { + try { + $status = get-service -name pcasvc -ErrorAction Stop + if($status.Status -ne "Stopped"){ + return @{ + Message = "Compliant - AppCompat Service is disabled (no inventory data will be collected)." + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + catch [System.SystemException]{ + return @{ + Message = "Service not found!" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63663 B" + Task = "The Application Compatibility Program Inventory must be prevented from collecting data and sending the information to Microsoft." + Test = { + try { + $status = get-service -name pcasvc -ErrorAction Stop + if($status.Status -ne "Stopped"){ + return @{ + Message = "Compliant - AppCompat Service is disabled (no inventory data will be collected)." + Status = "True" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppCompat" ` + -Name "DisableInventory" ` + | Select-Object -ExpandProperty "DisableInventory" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + catch [System.SystemException]{ + return @{ + Message = "Service not found!" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63665" + Task = "The system must be configured to require a strong session key." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63667" + Task = "Autoplay must be turned off for non-volume devices." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63669" + Task = "The machine inactivity limit must be set to 15 minutes, locking the system with the screensaver." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if ($regValue -ne 900) { + return @{ + Message = "Registry value is '$regValue'. Expected: 900" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63671" + Task = "The default autorun behavior must be configured to prevent autorun commands." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63673" + Task = "Autoplay must be disabled for all drives." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63677" + Task = "Enhanced anti-spoofing for facial recognition must be enabled on Window 10." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63679" + Task = "Administrator accounts must not be enumerated during elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63689" + Task = "Explorer Data Execution Prevention must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63691" + Task = "Turning off File Explorer heap termination on corruption must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63695" + Task = "File Explorer shell protocol must run in protected mode." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63699" + Task = "Users must not be allowed to ignore Windows Defender SmartScreen filter warnings for malicious websites in Microsoft Edge." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63701" + Task = "Users must not be allowed to ignore Windows Defender SmartScreen filter warnings for unverified files in Microsoft Edge." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "PreventOverrideAppRepUnknown" ` + | Select-Object -ExpandProperty "PreventOverrideAppRepUnknown" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63703" + Task = "The Windows SMB client must be configured to always perform SMB packet signing." + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-63709" + Task = "The password manager function in the Edge browser must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main" ` + -Name "FormSuggest Passwords" ` + | Select-Object -ExpandProperty "FormSuggest Passwords" + + if ($regValue -ne "no") { + return @{ + Message = "Registry value is '$regValue'. Expected: no" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63711" + Task = "Unencrypted passwords must not be sent to third-party SMB Servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63713" + Task = "The Windows Defender SmartScreen filter for Microsoft Edge must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63717" + Task = "The use of a hardware security device with Windows Hello for Business must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PassportForWork" ` + -Name "RequireSecurityDevice" ` + | Select-Object -ExpandProperty "RequireSecurityDevice" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63719" + Task = "The Windows SMB server must be configured to always perform SMB packet signing." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-63721" + Task = "Windows 10 must be configured to require a minimum pin length of six characters or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PassportForWork\PINComplexity" ` + -Name "MinimumPINLength" ` + | Select-Object -ExpandProperty "MinimumPINLength" + + if (($regValue -lt 6)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 6" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63729" + Task = "Passwords must not be saved in the Remote Desktop Client." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63731" + Task = "Local drives must be prevented from sharing with Remote Desktop Session Hosts." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63733" + Task = "Remote Desktop Services must always prompt a client for passwords upon connection." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63737" + Task = "The Remote Desktop Session Host must require secure RPC communications." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63741" + Task = "Remote Desktop Services must be configured with the client connection encryption set to the required level." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63743" + Task = "Attachments must be prevented from being downloaded from RSS feeds." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63745" + Task = "Anonymous enumeration of SAM accounts must not be allowed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63747" + Task = "Basic authentication for RSS feeds over HTTP must not be used." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "AllowBasicAuthInClear" ` + | Select-Object -ExpandProperty "AllowBasicAuthInClear" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63749" + Task = "Anonymous enumeration of shares must be restricted." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63751" + Task = "Indexing of encrypted files must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63755" + Task = "The system must be configured to prevent anonymous users from having the same rights as the Everyone group." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63759" + Task = "Anonymous access to Named Pipes and Shares must be restricted." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63765" + Task = "NTLM must be prevented from falling back to a Null session." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA\MSV1_0" ` + -Name "allownullsessionfallback" ` + | Select-Object -ExpandProperty "allownullsessionfallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63767" + Task = "PKU2U authentication using online identities must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63795" + Task = "Kerberos encryption types must be configured to prevent the use of DES and RC4 encryption suites." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63797" + Task = "The system must be configured to prevent the storage of the LAN Manager hash of passwords." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63801" + Task = "The LanMan authentication level must be set to send NTLMv2 response only, and to refuse LM and NTLM." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63803" + Task = "The system must be configured to the required LDAP client signing level." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63805" + Task = "The system must be configured to meet the minimum session security requirement for NTLM SSP based clients." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63807" + Task = "The system must be configured to meet the minimum session security requirement for NTLM SSP based servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63811" + Task = "The system must be configured to use FIPS-compliant algorithms for encryption, hashing, and signing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63815" + Task = "The default permissions of global system objects must be increased." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63817" + Task = "User Account Control approval mode for the built-in Administrator must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63821" + Task = "User Account Control must automatically deny elevation requests for standard users." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63825" + Task = "User Account Control must be configured to detect application installations and prompt for elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63827" + Task = "User Account Control must only elevate UIAccess applications that are installed in secure locations." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63829" + Task = "User Account Control must run all administrators in Admin Approval Mode, enabling UAC." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63831" + Task = "User Account Control must virtualize file and registry write failures to per-user locations." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63839" + Task = "Toast notifications to the lock screen must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63841" + Task = "Zone information must be preserved when saving attachments." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-68817" + Task = "Command line data must be included in process creation events." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-68819" + Task = "PowerShell script block logging must be enabled on Windows 10." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-68849" + Task = "Structured Exception Handling Overwrite Protection (SEHOP) must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-71763" + Task = "WDigest Authentication must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Wdigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-71765" + Task = "Internet connection sharing must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-71769" + Task = "Remote calls to the Security Account Manager (SAM) must be restricted to Administrators." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictRemoteSAM" ` + | Select-Object -ExpandProperty "RestrictRemoteSAM" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-71771" + Task = "Microsoft consumer experiences must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-74417" + Task = "Windows 10 must be configured to disable Windows Game Recording and Broadcasting." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR" ` + -Name "AllowGameDVR" ` + | Select-Object -ExpandProperty "AllowGameDVR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-74699" + Task = "Windows 10 must be configured to enable Remote host allows delegation of non-exportable credentials." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-74723" + Task = "The Server Message Block (SMB) v1 protocol must be disabled on the SMB server." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-74725" + Task = "The Server Message Block (SMB) v1 protocol must be disabled on the SMB client." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-82137" + Task = "The use of personal accounts for OneDrive synchronization must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\OneDrive" ` + -Name "DisablePersonalSync" ` + | Select-Object -ExpandProperty "DisablePersonalSync" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-82139" + Task = "Windows 10 must be configured to prevent certificate error overrides in Microsoft Edge." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Internet Settings" ` + -Name "PreventCertErrorOverrides" ` + | Select-Object -ExpandProperty "PreventCertErrorOverrides" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-82145" + Task = "If Enhanced diagnostic data is enabled it must be limited to the minimum required to support Windows Analytics." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitEnhancedDiagnosticDataWindowsAnalytics" ` + | Select-Object -ExpandProperty "LimitEnhancedDiagnosticDataWindowsAnalytics" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-94719" + Task = "Windows 10 must be configured to prevent Windows apps from being activated by voice while the system is locked." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsActivateWithVoiceAboveLock" ` + | Select-Object -ExpandProperty "LetAppsActivateWithVoiceAboveLock" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-94859" + Task = "Windows 10 systems must use a BitLocker PIN for pre-boot authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseAdvancedStartup" ` + | Select-Object -ExpandProperty "UseAdvancedStartup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-94861" + Task = "Windows 10 systems must use a BitLocker PIN with a minimum length of 6 digits for pre-boot authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "MinimumPIN" ` + | Select-Object -ExpandProperty "MinimumPIN" + + if (($regValue -lt 6)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 6" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-99557" + Task = "Windows 10 Kernel (Direct Memory Access) DMA Protection must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-99563" + Task = "Windows 10 should be configured to prevent users from receiving suggestions for third-party or additional applications. " + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#SecurityOptions.ps1 new file mode 100644 index 0000000..2d8a345 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#SecurityOptions.ps1 @@ -0,0 +1,130 @@ +[AuditTest] @{ + Id = "V-63601" + Task = "The built-in administrator account must be disabled." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableAdminAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableAdminAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63611" + Task = "The built-in guest account must be disabled." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63619" + Task = "The built-in administrator account must be renamed." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?!.*\bAdministrator\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63625" + Task = "The built-in guest account must be renamed." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-63739" + Task = "Anonymous SID/Name translation must not be allowed." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#UserRights.ps1 new file mode 100644 index 0000000..34ef58f --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-DISA-V1R23#UserRights.ps1 @@ -0,0 +1,956 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + if ($sidAccount.Translate([System.Security.Principal.NTAccount]) -eq "NULL SID") { + return @{ + Account = $null + Sid = $sidAccount.Value + } + } else { + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "V-63843" + Task = "The Access Credential Manager as a trusted caller user right must not be assigned to any groups or accounts." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63845" + Task = "The Access this computer from the network user right must only be assigned to the Administrators and Remote Desktop Users groups." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "Administrators" + "Remote Desktop Users" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63847" + Task = "The Act as part of the operating system user right must not be assigned to any groups or accounts." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63851" + Task = "The Allow log on locally user right must only be assigned to the Administrators and Users groups." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "Administrators" + "Users" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63853" + Task = "The Back up files and directories user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "Administrators" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63857" + Task = "The Create a pagefile user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "Administrators" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63859" + Task = "The Create a token object user right must not be assigned to any groups or accounts." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63861" + Task = "The Create global objects user right must only be assigned to Administrators, Service, Local Service, and Network Service." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "Administrators" + "LOCAL SERVICE" + "NETWORK SERVICE" + "SERVICE" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63863" + Task = "The Create permanent shared objects user right must not be assigned to any groups or accounts." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63865" + Task = "The Create symbolic links user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "Administrators" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63869" + Task = "The Debug programs user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "Administrators" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63871" + Task = "The Deny access to this computer from the network user right on workstations must be configured to prevent access from highly privileged domain accounts and local accounts on domain systems and unauthenticated access on all systems." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "Guests" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63877" + Task = "The Deny log on locally user right on workstations must be configured to prevent access from highly privileged domain accounts on domain systems and unauthenticated access on all systems." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "Enterprise Admins" + "Domain Admins" + "Guests" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63879" + Task = "The Deny log on through Remote Desktop Services user right on Windows 10 workstations must at a minimum be configured to prevent access from highly privileged domain accounts and local accounts on domain systems and unauthenticated access on all systems." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "Enterprise Admins" + "Domain Admins" + "Local account" + "Guests" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63881" + Task = "The Enable computer and user accounts to be trusted for delegation user right must not be assigned to any groups or accounts." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63883" + Task = "The Force shutdown from a remote system user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "Administrators" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63889" + Task = "The Impersonate a client after authentication user right must only be assigned to Administrators, Service, Local Service, and Network Service." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "Administrators" + "LOCAL SERVICE" + "NETWORK SERVICE" + "SERVICE" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63917" + Task = "The Load and unload device drivers user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "Administrators" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63925" + Task = "The Lock pages in memory user right must not be assigned to any groups or accounts." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63927" + Task = "The Manage auditing and security log user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "Administrators" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63931" + Task = "The Modify firmware environment values user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "Administrators" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63933" + Task = "The Perform volume maintenance tasks user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "Administrators" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63935" + Task = "The Profile single process user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "Administrators" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63939" + Task = "The Restore files and directories user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "Administrators" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-63941" + Task = "The Take ownership of files or other objects user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "Administrators" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#AccountPolicies.ps1 new file mode 100644 index 0000000..35fa9a8 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#AccountPolicies.ps1 @@ -0,0 +1,196 @@ +[AuditTest] @{ + Id = "AccountPolicy-216" + Task = "Ensure 'MinimumPasswordLength' is set to '14'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 14) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-217" + Task = "Ensure 'PasswordComplexity' is set to '1'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-218" + Task = "Ensure 'PasswordHistorySize' is set to '24'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-219" + Task = "Ensure 'LockoutBadCount' is set to '10'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 10 -or $setPolicy -le 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 10 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-220" + Task = "Ensure 'ResetLockoutCount' is set to '15'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 15) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-221" + Task = "Ensure 'LockoutDuration' is set to '15'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 15) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-222" + Task = "Ensure 'ClearTextPassword' is set to '0'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#AuditPolicies.ps1 new file mode 100644 index 0000000..b4a4804 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#AuditPolicies.ps1 @@ -0,0 +1,1388 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "AuditPolicy-193" + Task = "Ensure 'Credential Validation' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-194" + Task = "Ensure 'Security Group Management' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-195" + Task = "Ensure 'User Account Management' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-196" + Task = "Ensure 'Plug and Play Events' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-197" + Task = "Ensure 'Process Creation' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-198" + Task = "Ensure 'Account Lockout' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-199" + Task = "Ensure 'Group Membership' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-200" + Task = "Ensure 'Logon' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-201" + Task = "Ensure 'Other Logon/Logoff Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-202" + Task = "Ensure 'Special Logon' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-203" + Task = "Ensure 'Detailed File Share' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-204" + Task = "Ensure 'File Share' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-205" + Task = "Ensure 'Other Object Access Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-206" + Task = "Ensure 'Removable Storage' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-207" + Task = "Ensure 'Audit Policy Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-208" + Task = "Ensure 'Authentication Policy Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-209" + Task = "Ensure 'MPSSVC Rule-Level Policy Change' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory MPSSVC Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "MPSSVC Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'MPSSVC Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-210" + Task = "Ensure 'Other Policy Change Events' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-211" + Task = "Ensure 'Sensitive Privilege Use' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-212" + Task = "Ensure 'Other System Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-213" + Task = "Ensure 'Security State Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-214" + Task = "Ensure 'Security System Extension' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-215" + Task = "Ensure 'System Integrity' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#RegistrySettings.ps1 new file mode 100644 index 0000000..1a84a2e --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#RegistrySettings.ps1 @@ -0,0 +1,10968 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$avstatus = CheckForActiveAV +$windefrunning = CheckWindefRunning +$hyperVStatus = CheckHyperVStatus +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "Registry-001" + Task = "Set registry value 'PUAProtection' to 1." + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-002" + Task = "Set registry value 'MpCloudBlockLevel' to 2." + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\MpEngine" ` + -Name "MpCloudBlockLevel" ` + | Select-Object -ExpandProperty "MpCloudBlockLevel" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-003" + Task = "Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'." + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-004" + Task = "Ensure 'Turn off real-time protection' is set to 'Disabled'." + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-005" + Task = "Ensure 'Scan removable drives' is set to 'Enabled'." + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-006" + Task = "Ensure 'Send file samples when further analysis is required' is set to 'Send safe samples'." + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SubmitSamplesConsent" ` + | Select-Object -ExpandProperty "SubmitSamplesConsent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-007" + Task = "Ensure 'Join Microsoft MAPS' is set to 'Advanced MAPS'." + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-008" + Task = "Ensure 'Configure the 'Block at First Sight' feature' is set to 'Enabled'." + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "DisableBlockAtFirstSeen" ` + | Select-Object -ExpandProperty "DisableBlockAtFirstSeen" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-009" + Task = "Set registry value 'ExploitGuard_ASR_Rules' to 1." + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-010" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from injecting code into other processes)" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-011" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from creating executable content)" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-012" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from creating child processes)" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-013" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Win32 API calls from Office macro)" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-014" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block execution of potentially obfuscated scripts)" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-015" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block JavaScript or VBScript from launching downloaded executable content)" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-016" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block executable content from email client and webmail)" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-017" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block credential stealing from the Windows local security authority subsystem (lsass.exe))" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-018" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block untrusted and unsigned processes that run from USB)" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-019" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office communication application from creating child processes)" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-020" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Adobe Reader from creating child processes)" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-021" + Task = "Ensure 'Configure Attack Surface Reduction rules' is configured (Use advanced protection against ransomware)" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "c1db55ab-c21a-4637-bb3f-a12568109d35" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "c1db55ab-c21a-4637-bb3f-a12568109d35" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-022" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block persistence through WMI event subscription)" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-023" + Task = "Set registry value 'EnableNetworkProtection' to 1." + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-024" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-025" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Secure Boot'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if ($regValue -eq 3) { + return @{ + Message = "Set to 'Secure Boot and DMA Protection' which is more secure." + Status = "True" + } + } + + if ($regValue -ne 1 -and $regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or (better) 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-026" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled with UEFI lock'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-027" + Task = "Set registry value 'HVCIMATRequired' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HVCIMATRequired" ` + | Select-Object -ExpandProperty "HVCIMATRequired" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-028" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled with UEFI lock'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-029" + Task = "Set registry value 'ConfigureSystemGuardLaunch' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureSystemGuardLaunch" ` + | Select-Object -ExpandProperty "ConfigureSystemGuardLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-031" + Task = "Set registry value 'UseEnhancedPin' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseEnhancedPin" ` + | Select-Object -ExpandProperty "UseEnhancedPin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-032" + Task = "Set registry value 'RDVDenyCrossOrg' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVDenyCrossOrg" ` + | Select-Object -ExpandProperty "RDVDenyCrossOrg" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-033" + Task = "Set registry value 'DisableExternalDMAUnderLock' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "DisableExternalDMAUnderLock" ` + | Select-Object -ExpandProperty "DisableExternalDMAUnderLock" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-034" + Task = "Set registry value 'DCSettingIndex' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-035" + Task = "Set registry value 'ACSettingIndex' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-036" + Task = "Set registry value 'DenyDeviceClasses' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClasses" ` + | Select-Object -ExpandProperty "DenyDeviceClasses" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-037" + Task = "Set registry value 'DenyDeviceClassesRetroactive' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClassesRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceClassesRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-038" + Task = "Set registry value '1' to {d48179be-ec20-11d1-b6b8-00c04fa372a7}." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "{d48179be-ec20-11d1-b6b8-00c04fa372a7}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {d48179be-ec20-11d1-b6b8-00c04fa372a7}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-039" + Task = "Ensure 'Deny write access to removable drives not protected by BitLocker' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\Microsoft\FVE" ` + -Name "RDVDenyWriteAccess" ` + | Select-Object -ExpandProperty "RDVDenyWriteAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-040" + Task = "Set registry value 'AutoConnectAllowedOEM' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\WcmSvc\wifinetworkmanager\config" ` + -Name "AutoConnectAllowedOEM" ` + | Select-Object -ExpandProperty "AutoConnectAllowedOEM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-041" + Task = "Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-042" + Task = "Ensure 'Turn off Autoplay' is set to 'All drives'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-043" + Task = "Set registry value 'NoWebServices' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-044" + Task = "Ensure 'Set the default behavior for AutoRun' is set to 'Do not execute any autorun commands'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-045" + Task = "Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-046" + Task = "Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-047" + Task = "Set registry value 'LocalAccountTokenFilterPolicy' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-048" + Task = "Set registry value 'AllowEncryptionOracle' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-049" + Task = "Set registry value 'EnhancedAntiSpoofing' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-050" + Task = "Ensure 'Prevent downloading of enclosures' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-051" + Task = "Set registry value 'PreventCertErrorOverrides' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\MicrosoftEdge\Internet Settings" ` + -Name "PreventCertErrorOverrides" ` + | Select-Object -ExpandProperty "PreventCertErrorOverrides" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-052" + Task = "Set registry value 'FormSuggest Passwords' to no." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\MicrosoftEdge\Main" ` + -Name "FormSuggest Passwords" ` + | Select-Object -ExpandProperty "FormSuggest Passwords" + + if ($regValue -ne "no") { + return @{ + Message = "Registry value is '$regValue'. Expected: no" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-053" + Task = "Set registry value 'EnabledV9' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-054" + Task = "Set registry value 'PreventOverride' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-055" + Task = "Set registry value 'PreventOverrideAppRepUnknown' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "PreventOverrideAppRepUnknown" ` + | Select-Object -ExpandProperty "PreventOverrideAppRepUnknown" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-056" + Task = "Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-057" + Task = "Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-058" + Task = "Set registry value 'LetAppsActivateWithVoiceAboveLock' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsActivateWithVoiceAboveLock" ` + | Select-Object -ExpandProperty "LetAppsActivateWithVoiceAboveLock" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-059" + Task = "Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-060" + Task = "Set registry value 'AllowProtectedCreds' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-061" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '32768'. [Application\MaxSize]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-062" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '196608'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-063" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '32768'. [System\MaxSize]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-064" + Task = "Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-065" + Task = "Set registry value 'AllowGameDVR' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\GameDVR" ` + -Name "AllowGameDVR" ` + | Select-Object -ExpandProperty "AllowGameDVR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-066" + Task = "Ensure 'Configure registry policy processing' is set to '0'. [NoGPOListChanges]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-067" + Task = "Ensure 'Configure registry policy processing' is set to '0'. [NoBackgroundPolicy]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-068" + Task = "Set registry value 'AlwaysInstallElevated' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-069" + Task = "Ensure 'Allow user control over installs' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-070" + Task = "Set registry value 'DeviceEnumerationPolicy' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-071" + Task = "Ensure 'Enable insecure guest logons' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-072" + Task = "Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-073" + Task = "Set registry value '\\*\SYSVOL' to RequireMutualAuthentication=1, RequireIntegrity=1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if ($regValue -notmatch "^(?:RequireMutualAuthentication=1,\s*RequireIntegrity=1|RequireIntegrity=1,\s*RequireMutualAuthentication=1)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: RequireMutualAuthentication=1, RequireIntegrity=1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-074" + Task = "Set registry value '\\*\NETLOGON' to RequireMutualAuthentication=1, RequireIntegrity=1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if ($regValue -notmatch "^(?:RequireMutualAuthentication=1,\s*RequireIntegrity=1|RequireIntegrity=1,\s*RequireMutualAuthentication=1)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: RequireMutualAuthentication=1, RequireIntegrity=1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-075" + Task = "Set registry value 'NoLockScreenCamera' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-076" + Task = "Set registry value 'NoLockScreenSlideshow' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-077" + Task = "Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'. (EnableScriptBlockLogging)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-078" + Task = "Ensure 'Turn on PowerShell Script Block Logging' is not set. (EnableScriptBlockInvocationLogging)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockInvocationLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockInvocationLogging" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-079" + Task = "Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-080" + Task = "Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-081" + Task = "Ensure 'Configure Windows SmartScreen' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-082" + Task = "Set registry value 'ShellSmartScreenLevel' to Block." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-083" + Task = "Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($regValue -eq 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-084" + Task = "Set registry value 'AllowIndexingEncryptedStoresOrItems' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-085" + Task = "Ensure 'Disallow Digest authentication' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-086" + Task = "Ensure 'Allow unencrypted traffic' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-087" + Task = "Ensure 'Allow Basic authentication' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-088" + Task = "Ensure 'Allow unencrypted traffic' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-089" + Task = "Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-090" + Task = "Ensure 'Allow Basic authentication' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-091" + Task = "Ensure 'Turn off multicast name resolution' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-092" + Task = "Set registry value 'DisableWebPnPDownload' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-093" + Task = "Ensure 'Restrict Unauthenticated RPC clients' is set to 'Authenticated'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-094" + Task = "Solicited Remote Assistance - Set method for sending email invitations to 'Simple MAPI'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fUseMailto" ` + | Select-Object -ExpandProperty "fUseMailto" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-095" + Task = "Configure Solicited Remote Assistance to disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-096" + Task = "Configure Solicited Remote Assistance - Allow helpers to only view the computer." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowFullControl" ` + | Select-Object -ExpandProperty "fAllowFullControl" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-097" + Task = "Set registry value 'MaxTicketExpiry' to ." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxTicketExpiry" ` + | Select-Object -ExpandProperty "MaxTicketExpiry" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-098" + Task = "Set registry value 'MaxTicketExpiryUnits' to ." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxTicketExpiryUnits" ` + | Select-Object -ExpandProperty "MaxTicketExpiryUnits" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-099" + Task = "Set registry value 'MinEncryptionLevel' to 3." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-100" + Task = "Set registry value 'fPromptForPassword' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-101" + Task = "Set registry value 'fDisableCdm' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-102" + Task = "Set registry value 'DisablePasswordSaving' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-103" + Task = "Set registry value 'fEncryptRPCTraffic' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-105" + Task = "Domain: Set registry value 'DefaultOutboundAction' to 0." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-106" + Task = "Domain: Set registry value 'DisableNotifications' to 1." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-107" + Task = "Domain: Set registry value 'EnableFirewall' to 1." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-108" + Task = "Domain: Set registry value 'DefaultInboundAction' to 1." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-109" + Task = "Domain: Set registry value 'LogDroppedPackets' to 1." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-110" + Task = "Domain: Set registry value 'LogFileSize' to 16384." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-111" + Task = "Domain: Set registry value 'LogSuccessfulConnections' to 1." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-112" + Task = "Private: Set registry value 'EnableFirewall' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-113" + Task = "Private: Set registry value 'DisableNotifications' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-114" + Task = "Private: Set registry value 'DefaultInboundAction' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-115" + Task = "Private: Set registry value 'DefaultOutboundAction' to 0." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-116" + Task = "Private: Set registry value 'LogSuccessfulConnections' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-117" + Task = "Private: Set registry value 'LogDroppedPackets' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-118" + Task = "Private: Set registry value 'LogFileSize' to 16384." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-119" + Task = "Public: Set registry value 'DefaultOutboundAction' to 0." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-120" + Task = "Public: Set registry value 'EnableFirewall' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-121" + Task = "Public: Set registry value 'DisableNotifications' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-122" + Task = "Public: Set registry value 'AllowLocalIPsecPolicyMerge' to 0." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-123" + Task = "Public: Set registry value 'AllowLocalPolicyMerge' to 0." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-124" + Task = "Public: Set registry value 'DefaultInboundAction' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-125" + Task = "Public: Set registry value 'LogFileSize' to 16384." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-126" + Task = "Public: Set registry value 'LogDroppedPackets' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-127" + Task = "Public: Set registry value 'LogSuccessfulConnections' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-128" + Task = "Ensure 'Allow Windows Ink Workspace' is set to 'On, but disallow access above lock'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-129" + Task = "Set registry value 'AdmPwdEnabled' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft Services\AdmPwd" ` + -Name "AdmPwdEnabled" ` + | Select-Object -ExpandProperty "AdmPwdEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-130" + Task = "Ensure 'WDigest Authentication (disabling may require KB2871997)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-131" + Task = "Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-132" + Task = "Set registry value 'DriverLoadPolicy' to 3." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-133" + Task = "Ensure 'Configure SMB v1 server' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-134" + Task = "Ensure 'Configure SMB v1 client driver' is set to 'Disable driver (recommended)'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MrxSmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-135" + Task = "Set registry value 'NoNameReleaseOnDemand' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NoNameReleaseOnDemand" ` + | Select-Object -ExpandProperty "NoNameReleaseOnDemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-136" + Task = "Set registry value 'NodeType' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-137" + Task = "Set registry value 'EnableICMPRedirect' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-138" + Task = "Set registry value 'DisableIPSourceRouting' to 2. [Tcpip\Parameters\DisableIPSourceRouting]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-139" + Task = "Set registry value 'DisableIPSourceRouting' to 2. [Tcpip6\Parameters\DisableIPSourceRouting]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-140" + Task = "Set registry value 'ScRemoveOption' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-141" + Task = "Set registry value 'InactivityTimeoutSecs' to 900." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if ($regValue -ne 900) { + return @{ + Message = "Registry value is '$regValue'. Expected: 900" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-142" + Task = "Set registry value 'NoLMHash' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-143" + Task = "Set registry value 'EnablePlainTextPassword' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-144" + Task = "Set registry value 'LimitBlankPasswordUse' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-145" + Task = "Set registry value 'RestrictAnonymousSAM' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-146" + Task = "Set registry value 'RestrictAnonymous' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-147" + Task = "Set registry value 'RestrictNullSessAccess' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-148" + Task = "Set registry value 'SCENoApplyLegacyAuditPolicy' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-149" + Task = "Set registry value 'NTLMMinClientSec' to 537395200." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-150" + Task = "Set registry value 'LmCompatibilityLevel' to 5." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-151" + Task = "Set registry value 'allownullsessionfallback' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "allownullsessionfallback" ` + | Select-Object -ExpandProperty "allownullsessionfallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-152" + Task = "Set registry value 'NTLMMinServerSec' to 537395200." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-153" + Task = "Set registry value 'requirestrongkey' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "requirestrongkey" ` + | Select-Object -ExpandProperty "requirestrongkey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-154" + Task = "Set registry value 'RequireSecuritySignature' to 1." + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Registry-155" + Task = "Set registry value 'sealsecurechannel' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "sealsecurechannel" ` + | Select-Object -ExpandProperty "sealsecurechannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-156" + Task = "Set registry value 'requiresignorseal' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "requiresignorseal" ` + | Select-Object -ExpandProperty "requiresignorseal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-157" + Task = "Set registry value 'signsecurechannel' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "signsecurechannel" ` + | Select-Object -ExpandProperty "signsecurechannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-158" + Task = "Set registry value 'requiresecuritysignature' to 1." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Registry-159" + Task = "Set registry value 'ProtectionMode' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-160" + Task = "Set registry value 'ConsentPromptBehaviorAdmin' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-161" + Task = "Set registry value 'EnableSecureUIAPaths' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-162" + Task = "Set registry value 'EnableLUA' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-163" + Task = "Set registry value 'ConsentPromptBehaviorUser' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-164" + Task = "Set registry value 'EnableInstallerDetection' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-165" + Task = "Set registry value 'FilterAdministratorToken' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-166" + Task = "Set registry value 'EnableVirtualization' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-167" + Task = "Set registry value 'LDAPClientIntegrity' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-168" + Task = "Set registry value 'RestrictRemoteSAM' to O:BAG:BAD:(A;;RC;;;BA)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictRemoteSAM" ` + | Select-Object -ExpandProperty "RestrictRemoteSAM" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-223" + Task = "Ensure 'Do not suggest third-party content in Windows spotlight' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-224" + Task = "Set registry value 'NoToastApplicationNotificationOnLockScreen' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-225" + Task = "Set registry value 'FormSuggest Passwords' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "FormSuggest Passwords" ` + | Select-Object -ExpandProperty "FormSuggest Passwords" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-226" + Task = "Ensure 'Turn on the auto-complete feature for user names and passwords on forms' is set to 'no'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "FormSuggest PW Ask" ` + | Select-Object -ExpandProperty "FormSuggest PW Ask" + + if ($regValue -ne "no") { + return @{ + Message = "Registry value is '$regValue'. Expected: no" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-227" + Task = "Set registry value 'FormSuggest Passwords' to no." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "FormSuggest Passwords" ` + | Select-Object -ExpandProperty "FormSuggest Passwords" + + if ($regValue -ne "no") { + return @{ + Message = "Registry value is '$regValue'. Expected: no" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-228" + Task = "Ensure 'Remove `"Run this time`" button for outdated ActiveX controls in Internet Explorer ' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "RunThisTimeEnabled" ` + | Select-Object -ExpandProperty "RunThisTimeEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-229" + Task = "Ensure 'Turn off blocking of outdated ActiveX controls for Internet Explorer' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "VersionCheckEnabled" ` + | Select-Object -ExpandProperty "VersionCheckEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-230" + Task = "Ensure 'Allow software to run or install even if the signature is invalid' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "RunInvalidSignatures" ` + | Select-Object -ExpandProperty "RunInvalidSignatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-231" + Task = "Set registry value 'CheckExeSignatures' to yes." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "CheckExeSignatures" ` + | Select-Object -ExpandProperty "CheckExeSignatures" + + if ($regValue -ne "yes") { + return @{ + Message = "Registry value is '$regValue'. Expected: yes" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-232" + Task = "Ensure 'Turn on 64-bit tab processes when running in Enhanced Protected Mode on 64-bit versions of Windows' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation64Bit" ` + | Select-Object -ExpandProperty "Isolation64Bit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-233" + Task = "Ensure 'Do not allow ActiveX controls to run in Protected Mode when Enhanced Protected Mode is enabled' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "DisableEPMCompat" ` + | Select-Object -ExpandProperty "DisableEPMCompat" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-234" + Task = "Set registry value 'Isolation' to PMEM." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation" ` + | Select-Object -ExpandProperty "Isolation" + + if ($regValue -ne "PMEM") { + return @{ + Message = "Registry value is '$regValue'. Expected: PMEM" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-235" + Task = "Set registry value '(Reserved)' to 1. [FEATURE_DISABLE_MK_PROTOCOL\(Reserved)]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-236" + Task = "Set registry value 'iexplore.exe' to 1. [FEATURE_DISABLE_MK_PROTOCOL\iexplore.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-237" + Task = "Set registry value 'explorer.exe' to 1. [FEATURE_DISABLE_MK_PROTOCOL\explorer.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-238" + Task = "Set registry value 'explorer.exe' to 1. [FEATURE_MIME_HANDLING\explorer.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-239" + Task = "Set registry value 'iexplore.exe' to 1. [FEATURE_MIME_HANDLING\iexplore.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-240" + Task = "Set registry value '(Reserved)' to 1. [FEATURE_MIME_HANDLING\(Reserved)]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-241" + Task = "Set registry value 'explorer.exe' to 1. [FEATURE_MIME_SNIFFING\explorer.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-242" + Task = "Set registry value 'iexplore.exe' to 1. [FEATURE_MIME_SNIFFING\iexplore.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-243" + Task = "Set registry value '(Reserved)' to 1. [FEATURE_MIME_SNIFFING\(Reserved)]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-244" + Task = "Set registry value '(Reserved)' to 1. [FEATURE_RESTRICT_ACTIVEXINSTALL\(Reserved)]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-245" + Task = "Set registry value 'explorer.exe' to 1. [FEATURE_RESTRICT_ACTIVEXINSTALL\explorer.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-246" + Task = "Set registry value 'iexplore.exe' to 1. [FEATURE_RESTRICT_ACTIVEXINSTALL\iexplore.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-247" + Task = "Set registry value '(Reserved)' to 1. [FEATURE_RESTRICT_FILEDOWNLOAD\(Reserved)]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-248" + Task = "Set registry value 'iexplore.exe' to 1. [FEATURE_RESTRICT_FILEDOWNLOAD\iexplore.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-249" + Task = "Set registry value 'explorer.exe' to 1. [FEATURE_RESTRICT_FILEDOWNLOAD\explorer.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-250" + Task = "Set registry value '(Reserved)' to 1. [FEATURE_SECURITYBAND\(Reserved)]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-251" + Task = "Set registry value 'iexplore.exe' to 1. [FEATURE_SECURITYBAND\iexplore.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-252" + Task = "Set registry value 'explorer.exe' to 1. [FEATURE_SECURITYBAND\explorer.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-253" + Task = "Set registry value 'iexplore.exe' to 1. [FEATURE_WINDOW_RESTRICTIONS\iexplore.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-254" + Task = "Set registry value '(Reserved)' to 1. [FEATURE_WINDOW_RESTRICTIONS\(Reserved)]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-255" + Task = "Set registry value 'explorer.exe' to 1. [FEATURE_WINDOW_RESTRICTIONS\explorer.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-256" + Task = "Set registry value '(Reserved)' to 1. [FEATURE_ZONE_ELEVATION\(Reserved)]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-257" + Task = "Set registry value 'explorer.exe' to 1. [FEATURE_ZONE_ELEVATION\explorer.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-258" + Task = "Set registry value 'iexplore.exe' to 1. [FEATURE_ZONE_ELEVATION\iexplore.exe]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-259" + Task = "Set registry value 'PreventOverrideAppRepUnknown' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverrideAppRepUnknown" ` + | Select-Object -ExpandProperty "PreventOverrideAppRepUnknown" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-260" + Task = "Set registry value 'PreventOverride' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-261" + Task = "Ensure 'Prevent managing SmartScreen Filter' is set to 'On'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-262" + Task = "Set registry value 'NoCrashDetection' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Restrictions" ` + -Name "NoCrashDetection" ` + | Select-Object -ExpandProperty "NoCrashDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-263" + Task = "Ensure 'Turn off the Security Settings Check feature' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security" ` + -Name "DisableSecuritySettingsCheck" ` + | Select-Object -ExpandProperty "DisableSecuritySettingsCheck" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-264" + Task = "Ensure 'Prevent per-user installation of ActiveX controls' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security\ActiveX" ` + -Name "BlockNonAdminActiveXInstall" ` + | Select-Object -ExpandProperty "BlockNonAdminActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-265" + Task = "Ensure 'Specify use of ActiveX Installer Service for installation of ActiveX controls' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AxInstaller" ` + -Name "OnlyUseAXISForActiveXInstall" ` + | Select-Object -ExpandProperty "OnlyUseAXISForActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-266" + Task = "Set registry value 'Security_zones_map_edit' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_zones_map_edit" ` + | Select-Object -ExpandProperty "Security_zones_map_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-267" + Task = "Set registry value 'Security_options_edit' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_options_edit" ` + | Select-Object -ExpandProperty "Security_options_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-268" + Task = "Set registry value 'Security_HKLM_only' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_HKLM_only" ` + | Select-Object -ExpandProperty "Security_HKLM_only" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-269" + Task = "Ensure 'Check for server certificate revocation' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "CertificateRevocation" ` + | Select-Object -ExpandProperty "CertificateRevocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-270" + Task = "Ensure 'Prevent ignoring certificate errors' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "PreventIgnoreCertErrors" ` + | Select-Object -ExpandProperty "PreventIgnoreCertErrors" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-271" + Task = "Set registry value 'WarnOnBadCertRecving' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "WarnOnBadCertRecving" ` + | Select-Object -ExpandProperty "WarnOnBadCertRecving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-272" + Task = "Ensure 'Allow fallback to SSL 3.0 (Internet Explorer)' is set to 'No Sites'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "EnableSSL3Fallback" ` + | Select-Object -ExpandProperty "EnableSSL3Fallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-273" + Task = "Ensure 'Turn off encryption support' is set to 'Use TLS 1.1 and TLS 1.2'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "SecureProtocols" ` + | Select-Object -ExpandProperty "SecureProtocols" + + if ($regValue -ne 2560) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2560" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-274" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-275" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-276" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-277" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Lockdown_Zones\3]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\3" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-278" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Lockdown_Zones\4]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-279" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-280" + Task = "Ensure 'Intranet Sites: Include all network paths (UNCs)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap" ` + -Name "UNCAsIntranet" ` + | Select-Object -ExpandProperty "UNCAsIntranet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-281" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-282" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-283" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-284" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-285" + Task = "Ensure 'Java permissions' is set to 'High safety'. [Zones\1\1C00]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-286" + Task = "Ensure 'Java permissions' is set to 'High safety'. [Zones\2\1C00]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-287" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-288" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-289" + Task = "Ensure 'Run .NET Framework-reliant components signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-290" + Task = "Ensure 'Allow script-initiated windows without size or position constraints' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-291" + Task = "Ensure 'Allow drag and drop or copy and paste files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-292" + Task = "Ensure 'Include local path when user is uploading files to a server' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-293" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-294" + Task = "Ensure 'Access data sources across domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-295" + Task = "Ensure 'Launching applications and files in an IFRAME' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-296" + Task = "Ensure 'Automatic prompting for file downloads' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-297" + Task = "Ensure 'Allow scriptlets' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-298" + Task = "Ensure 'Allow scripting of Internet Explorer WebBrowser controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-299" + Task = "Ensure 'Use Pop-up Blocker' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-300" + Task = "Ensure 'Turn on Protected Mode' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-301" + Task = "Ensure 'Allow updates to status bar via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-302" + Task = "Ensure 'Userdata persistence' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-303" + Task = "Ensure 'Allow loading of XAML files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-304" + Task = "Ensure 'Run .NET Framework-reliant components not signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-305" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-306" + Task = "Ensure 'Download signed ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-307" + Task = "Ensure 'Logon options' is set to 'Prompt for user name and password'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-308" + Task = "Ensure 'Enable dragging of content from different domains within a window' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-309" + Task = "Ensure 'Download unsigned ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-310" + Task = "Ensure 'Allow only approved domains to use ActiveX controls without prompt' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-311" + Task = "Ensure 'Allow cut, copy or paste operations from the clipboard via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-312" + Task = "Ensure 'Turn on Cross-Site Scripting Filter' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-313" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-314" + Task = "Ensure 'Navigate windows and frames across different domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-315" + Task = "Ensure 'Enable dragging of content from different domains across windows' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-316" + Task = "Ensure 'Web sites in less privileged Web content zones can navigate into this zone' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-317" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Zones\3]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-318" + Task = "Ensure 'Show security warning for potentially unsafe files' is set to 'Prompt'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-319" + Task = "Ensure 'Allow only approved domains to use the TDC ActiveX control' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120c" ` + | Select-Object -ExpandProperty "120c" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-320" + Task = "Set registry value '140C' to 3. (Zones\3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "140C" ` + | Select-Object -ExpandProperty "140C" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-321" + Task = "Ensure 'Allow META REFRESH' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1608" ` + | Select-Object -ExpandProperty "1608" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-322" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-323" + Task = "Ensure 'Download signed ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-324" + Task = "Ensure 'Navigate windows and frames across different domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-325" + Task = "Ensure 'Allow only approved domains to use ActiveX controls without prompt' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-326" + Task = "Ensure 'Use Pop-up Blocker' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-327" + Task = "Ensure 'Download unsigned ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-328" + Task = "Ensure 'Userdata persistence' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-329" + Task = "Ensure 'Allow cut, copy or paste operations from the clipboard via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-330" + Task = "Ensure 'Include local path when user is uploading files to a server' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-331" + Task = "Ensure 'Access data sources across domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-332" + Task = "Ensure 'Allow script-initiated windows without size or position constraints' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-333" + Task = "Ensure 'Run .NET Framework-reliant components not signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-334" + Task = "Ensure 'Automatic prompting for file downloads' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-335" + Task = "Ensure 'Allow binary and script behaviors' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2000" ` + | Select-Object -ExpandProperty "2000" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-336" + Task = "Ensure 'Scripting of Java applets' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1402" ` + | Select-Object -ExpandProperty "1402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-337" + Task = "Ensure 'Allow file downloads' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1803" ` + | Select-Object -ExpandProperty "1803" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-338" + Task = "Ensure 'Allow loading of XAML files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-339" + Task = "Ensure 'Allow active scripting' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1400" ` + | Select-Object -ExpandProperty "1400" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-340" + Task = "Ensure 'Logon options' is set to 'Anonymous logon'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-341" + Task = "Ensure 'Run .NET Framework-reliant components signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-342" + Task = "Ensure 'Turn on Protected Mode' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-343" + Task = "Ensure 'Turn on Cross-Site Scripting Filter' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-344" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-345" + Task = "Ensure 'Allow scriptlets' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-346" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-347" + Task = "Ensure 'Allow scripting of Internet Explorer WebBrowser controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-348" + Task = "Ensure 'Enable dragging of content from different domains within a window' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-349" + Task = "Ensure 'Allow drag and drop or copy and paste files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-350" + Task = "Ensure 'Allow updates to status bar via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-351" + Task = "Ensure 'Enable dragging of content from different domains across windows' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-352" + Task = "Ensure 'Script ActiveX controls marked safe for scripting' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1405" ` + | Select-Object -ExpandProperty "1405" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-353" + Task = "Ensure 'Web sites in less privileged Web content zones can navigate into this zone' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-354" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Zones\4]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-355" + Task = "Ensure 'Run ActiveX controls and plugins' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1200" ` + | Select-Object -ExpandProperty "1200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-356" + Task = "Ensure 'Launching applications and files in an IFRAME' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-357" + Task = "Ensure 'Show security warning for potentially unsafe files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-358" + Task = "Ensure 'Allow only approved domains to use the TDC ActiveX control' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120c" ` + | Select-Object -ExpandProperty "120c" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-359" + Task = "Set registry value '140C' to 3. (Zones\4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "140C" ` + | Select-Object -ExpandProperty "140C" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#SecurityOptions.ps1 new file mode 100644 index 0000000..d8ce1e4 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#SecurityOptions.ps1 @@ -0,0 +1,26 @@ +[AuditTest] @{ + Id = "SecurityOption-169" + Task = "Ensure 'LSAAnonymousNameLookup' is set to '0'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#UserRights.ps1 new file mode 100644 index 0000000..371406d --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Microsoft-21H1#UserRights.ps1 @@ -0,0 +1,882 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + if ($sidAccount.Translate([System.Security.Principal.NTAccount]) -eq "NULL SID") { + return @{ + Account = $null + Sid = $sidAccount.Value + } + } else { + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "UserRight-170" + Task = "Ensure 'SeSecurityPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-171" + Task = "Ensure 'SeRestorePrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-172" + Task = "Ensure 'SeTakeOwnershipPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-173" + Task = "Ensure 'SeBackupPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-174" + Task = "Ensure 'SeDenyRemoteInteractiveLogonRight' is set to 'S-1-5-113'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-175" + Task = "Ensure 'SeCreatePermanentPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-176" + Task = "Ensure 'SeManageVolumePrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-177" + Task = "Ensure 'SeLoadDriverPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-178" + Task = "Ensure 'SeLockMemoryPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-179" + Task = "Ensure 'SeDenyNetworkLogonRight' is set to 'S-1-5-113'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if ($missingUsers.Count -gt 0) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-180" + Task = "Ensure 'Access this computer from the network' is set to 'Administrator, Remote Desktop Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-181" + Task = "Ensure 'SeImpersonatePrivilege' is set to 'S-1-5-32-544, S-1-5-6, S-1-5-19, S-1-5-20'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-6" + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-182" + Task = "Ensure 'SeCreateTokenPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-183" + Task = "Ensure 'SeCreateGlobalPrivilege' is set to 'S-1-5-32-544, S-1-5-6, S-1-5-19, S-1-5-20'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-6" + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-184" + Task = "Ensure 'SeSystemEnvironmentPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-185" + Task = "Ensure 'SeCreatePagefilePrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-186" + Task = "Ensure 'SeInteractiveLogonRight' is set to 'S-1-5-32-544, S-1-5-32-545'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-187" + Task = "Ensure 'SeRemoteShutdownPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-188" + Task = "Ensure 'Debug programs' is set to 'Administrators'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-189" + Task = "Ensure 'SeTrustedCredManAccessPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-190" + Task = "Ensure 'SeProfileSingleProcessPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-191" + Task = "Ensure 'SeTcbPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-192" + Task = "Ensure 'SeEnableDelegationPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#AccountPolicies.ps1 new file mode 100644 index 0000000..7fa9cee --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#AccountPolicies.ps1 @@ -0,0 +1,255 @@ +[AuditTest] @{ + Id = "1.1.1" + Task = "(L1) Ensure 'Enforce password history' is set to '24 or more password(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "(L1) Ensure 'Maximum password age' is set to '365 or fewer days, but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 365 -or $setPolicy -le 0)) { + if($setPolicy -eq -1){ #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 365 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "(L1) Ensure 'Minimum password age' is set to '1 or more day(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 1)) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "(L1) Ensure 'Minimum password length' is set to '14 or more character(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.5" + Task = "(L1) Ensure 'Password must meet complexity requirements' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.7" + Task = "(L1) Ensure 'Store passwords using reversible encryption' is set to 'Disabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "(L1) Ensure 'Account lockout duration' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "(L1) Ensure 'Account lockout threshold' is set to '5 or fewer invalid logon attempt(s), but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -gt 5 -or $setPolicy -le 0) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 5 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.3" + Task = "(L1) Ensure 'Reset account lockout counter after' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#AuditPolicies.ps1 new file mode 100644 index 0000000..01bc89f --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#AuditPolicies.ps1 @@ -0,0 +1,1616 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "17.1.1" + Task = "(L1) Ensure 'Audit Credential Validation' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.1" + Task = "(L1) Ensure 'Audit Application Group Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Application Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Application Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Application Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.2" + Task = "(L1) Ensure 'Audit Security Group Management' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.3" + Task = "(L1) Ensure 'Audit User Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.1" + Task = "(L1) Ensure 'Audit PNP Activity' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.2" + Task = "(L1) Ensure 'Audit Process Creation' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.1" + Task = "(L1) Ensure 'Audit Account Lockout' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.2" + Task = "(L1) Ensure 'Audit Group Membership' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.3" + Task = "(L1) Ensure 'Audit Logoff' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.4" + Task = "(L1) Ensure 'Audit Logon' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.5" + Task = "(L1) Ensure 'Audit Other Logon/Logoff Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.6" + Task = "(L1) Ensure 'Audit Special Logon' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.1" + Task = "(L1) Ensure 'Audit Detailed File Share' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.2" + Task = "(L1) Ensure 'Audit File Share' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.3" + Task = "(L1) Ensure 'Audit Other Object Access Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.4" + Task = "(L1) Ensure 'Audit Removable Storage' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.1" + Task = "(L1) Ensure 'Audit Audit Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.2" + Task = "(L1) Ensure 'Audit Authentication Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.3" + Task = "(L1) Ensure 'Audit Authorization Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.4" + Task = "(L1) Ensure 'Audit MPSSVC Rule-Level Policy Change' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Mpssvc Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Mpssvc Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Mpssvc Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.5" + Task = "(L1) Ensure 'Audit Other Policy Change Events' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.8.1" + Task = "(L1) Ensure 'Audit Sensitive Privilege Use' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.1" + Task = "(L1) Ensure 'Audit IPsec Driver' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Ipsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Ipsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Ipsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.2" + Task = "(L1) Ensure 'Audit Other System Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.3" + Task = "(L1) Ensure 'Audit Security State Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.4" + Task = "(L1) Ensure 'Audit Security System Extension' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.5" + Task = "(L1) Ensure 'Audit System Integrity' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#RegistrySettings.ps1 new file mode 100644 index 0000000..2f0430c --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#RegistrySettings.ps1 @@ -0,0 +1,16305 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$avstatus = CheckForActiveAV +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "1.1.6" + Task = "(L1) Ensure 'Relax minimum password length limits' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SAM" ` + -Name "RelaxMinimumPasswordLengthLimits" ` + | Select-Object -ExpandProperty "RelaxMinimumPasswordLengthLimits" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.1" + Task = "(L1) Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "NoConnectedUser" ` + | Select-Object -ExpandProperty "NoConnectedUser" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.3" + Task = "(L1) Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.1" + Task = "(L1) Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.2" + Task = "(L1) Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "CrashOnAuditFail" ` + | Select-Object -ExpandProperty "CrashOnAuditFail" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4.1" + Task = "(L2) Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.1" + Task = "(L1) Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.2" + Task = "(L1) Ensure 'Interactive logon: Don't display last signed-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.3" + Task = "(BL) Ensure 'Interactive logon: Machine account lockout threshold' is set to '10 or fewer invalid logon attempts, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MaxDevicePasswordFailedAttempts" ` + | Select-Object -ExpandProperty "MaxDevicePasswordFailedAttempts" + + if (($regValue -gt 10 -or $regValue -le 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 10 and x > 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.4" + Task = "(L1) Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.5" + Task = "(L1) Configure 'Interactive logon: Message text for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.6" + Task = "(L1) Configure 'Interactive logon: Message title for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.7" + Task = "(L1) Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if (($regValue -lt 5 -or $regValue -gt 14)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 5 and x <= 14" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.8" + Task = "(L1) Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -notmatch "^(1|2|3)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(1|2|3)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.8.1" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.2" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True) { + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.3" + Task = "(L1) Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.1" + Task = "(L1) Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if (($regValue -gt 15)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.2" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.3" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True) { + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.4" + Task = "(L1) Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "enableforcedlogoff" ` + | Select-Object -ExpandProperty "enableforcedlogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.5" + Task = "(L1) Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "SMBServerNameHardeningLevel" ` + | Select-Object -ExpandProperty "SMBServerNameHardeningLevel" + + if (($regValue -lt 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.2" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.3" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.4" + Task = "(L1) Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.5" + Task = "(L1) Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.6" + Task = "(L1) Ensure 'Network access: Named Pipes that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.7" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\ProductOptions" + "System\CurrentControlSet\Control\Server Applications" + "Software\Microsoft\Windows NT\CurrentVersion" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\ProductOptions System\CurrentControlSet\Control\Server Applications Software\Microsoft\Windows NT\CurrentVersion" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.8" + Task = "(L1) Configure 'Network access: Remotely accessible registry paths and sub-paths'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9" + Task = "(L1) Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.10" + Task = "(L1) Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "restrictremotesam" ` + | Select-Object -ExpandProperty "restrictremotesam" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.11" + Task = "(L1) Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionShares" ` + | Select-Object -ExpandProperty "NullSessionShares" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.12" + Task = "(L1) Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.1" + Task = "(L1) Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.2" + Task = "(L1) Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.3" + Task = "(L1) Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.4" + Task = "(L1) Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.5" + Task = "(L1) Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.7" + Task = "(L1) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM&NTLM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.8" + Task = "(L1) Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if (($regValue -lt 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.9" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.10" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.14.1" + Task = "(L2) Ensure 'System cryptography: Force strong key protection for user keys stored on the computer' is set to 'User is prompted when the key is first used' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Cryptography" ` + -Name "ForceKeyProtection" ` + | Select-Object -ExpandProperty "ForceKeyProtection" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.1" + Task = "(L1) Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.2" + Task = "(L1) Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.1" + Task = "(L1) Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.2" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.3" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.4" + Task = "(L1) Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.5" + Task = "(L1) Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.6" + Task = "(L1) Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.7" + Task = "(L1) Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.8" + Task = "(L1) Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1" + Task = "(L2) Ensure 'Bluetooth Audio Gateway Service (BTAGService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTAGService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2" + Task = "(L2) Ensure 'Bluetooth Support Service (bthserv)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bthserv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.3" + Task = "(L1) Ensure 'Computer Browser (Browser)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.4" + Task = "(L2) Ensure 'Downloaded Maps Manager (MapsBroker)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MapsBroker" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.5" + Task = "(L2) Ensure 'Geolocation Service (lfsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lfsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.6" + Task = "(L1) Ensure 'IIS Admin Service (IISADMIN)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IISADMIN" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.7" + Task = "(L1) Ensure 'Infrared monitor service (irmon)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\irmon" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.8" + Task = "(L1) Ensure 'Internet Connection Sharing (ICS) (SharedAccess)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.9" + Task = "(L2) Ensure 'Link-Layer Topology Discovery Mapper (lltdsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lltdsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.10" + Task = "(L1) Ensure 'LxssManager (LxssManager)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LxssManager" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.11" + Task = "(L1) Ensure 'Microsoft FTP Service (FTPSVC)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FTPSVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.12" + Task = "(L2) Ensure 'Microsoft iSCSI Initiator Service (MSiSCSI)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSiSCSI" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.13" + Task = "(L1) Ensure 'OpenSSH SSH Server (sshd)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sshd" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.14" + Task = "(L2) Ensure 'Peer Name Resolution Protocol (PNRPsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.15" + Task = "(L2) Ensure 'Peer Networking Grouping (p2psvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2psvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.16" + Task = "(L2) Ensure 'Peer Networking Identity Manager (p2pimsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2pimsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.17" + Task = "(L2) Ensure 'PNRP Machine Name Publication Service (PNRPAutoReg)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPAutoReg" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.18" + Task = "(L2) Ensure 'Print Spooler (Spooler)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.19" + Task = "(L2) Ensure 'Problem Reports and Solutions Control Panel Support (wercplsupport)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wercplsupport" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.20" + Task = "(L2) Ensure 'Remote Access Auto Connection Manager (RasAuto)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasAuto" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.21" + Task = "(L2) Ensure 'Remote Desktop Configuration (SessionEnv)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SessionEnv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.22" + Task = "(L2) Ensure 'Remote Desktop Services (TermService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.23" + Task = "(L2) Ensure 'Remote Desktop Services UserMode Port Redirector (UmRdpService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UmRdpService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.24" + Task = "(L1) Ensure 'Remote Procedure Call (RPC) Locator (RpcLocator)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcLocator" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.25" + Task = "(L2) Ensure 'Remote Registry (RemoteRegistry)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteRegistry" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.26" + Task = "(L1) Ensure 'Routing and Remote Access (RemoteAccess)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.27" + Task = "(L2) Ensure 'Server (LanmanServer)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.28" + Task = "(L1) Ensure 'Simple TCP/IP Services (simptcp)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\simptcp" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.29" + Task = "(L2) Ensure 'SNMP Service (SNMP)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SNMP" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.30" + Task = "(L1) Ensure 'Special Administration Console Helper (sacsvr)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sacsvr" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.31" + Task = "(L1) Ensure 'SSDP Discovery (SSDPSRV)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SSDPSRV" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.32" + Task = "(L1) Ensure 'UPnP Device Host (upnphost)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\upnphost" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.33" + Task = "(L1) Ensure 'Web Management Service (WMSvc)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.34" + Task = "(L2) Ensure 'Windows Error Reporting Service (WerSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WerSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.35" + Task = "(L2) Ensure 'Windows Event Collector (Wecsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Wecsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.36" + Task = "(L1) Ensure 'Windows Media Player Network Sharing Service (WMPNetworkSvc)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMPNetworkSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.37" + Task = "(L1) Ensure 'Windows Mobile Hotspot Service (icssvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\icssvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.38" + Task = "(L2) Ensure 'Windows Push Notifications System Service (WpnService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WpnService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.39" + Task = "(L2) Ensure 'Windows PushToInstall Service (PushToInstall)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PushToInstall" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.40" + Task = "(L2) Ensure 'Windows Remote Management (WS-Management) (WinRM)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinRM" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.41" + Task = "(L1) Ensure 'World Wide Web Publishing Service (W3SVC)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.42" + Task = "(L1) Ensure 'Xbox Accessory Management Service (XboxGipSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxGipSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.43" + Task = "(L1) Ensure 'Xbox Live Auth Manager (XblAuthManager)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblAuthManager" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.44" + Task = "(L1) Ensure 'Xbox Live Game Save (XblGameSave)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblGameSave" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.45" + Task = "(L1) Ensure 'Xbox Live Networking Service (XboxNetApiSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxNetApiSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.2.1" + Task = "(L1) Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" ` + -Name "EnableFirewall" ` + | Select-Object -ExpandProperty "EnableFirewall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.2.2" + Task = "(L1) Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" ` + -Name "DefaultInboundAction" ` + | Select-Object -ExpandProperty "DefaultInboundAction" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.2.3" + Task = "(L1) Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.4" + Task = "(L1) Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.5" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\privatefw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\privatefw.log"; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.6" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.7" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.8" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.1" + Task = "(L1) Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.2" + Task = "(L1) Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.3" + Task = "(L1) Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.4" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.5" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.6" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.7" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\publicfw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\publicfw.log"; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.8" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.9" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.10" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "18.1.1.1" + Task = "(L1) Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.1.2" + Task = "(L1) Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.2.2" + Task = "(L1) Ensure 'Allow users to enable online speech recognition services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "AllowInputPersonalization" ` + | Select-Object -ExpandProperty "AllowInputPersonalization" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.3" + Task = "(L2) Ensure 'Allow Online Tips' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "AllowOnlineTips" ` + | Select-Object -ExpandProperty "AllowOnlineTips" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.1" + Task = "(L1) Ensure 'Configure RPC packet level privacy setting for incoming connections' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print" ` + -Name "RpcAuthnLevelPrivacyEnabled" ` + | Select-Object -ExpandProperty "RpcAuthnLevelPrivacyEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.2" + Task = "(L1) Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.3" + Task = "(L1) Ensure 'Configure SMB v1 server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.4" + Task = "(L1) Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.5" + Task = "(L1) Ensure 'LSA Protection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RunAsPPL" ` + | Select-Object -ExpandProperty "RunAsPPL" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.6" + Task = "(L1) Ensure 'NetBT NodeType configuration' is set to 'Enabled: P-node (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.7" + Task = "(L1) Ensure 'WDigest Authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.1" + Task = "(L1) Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.2" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.3" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.4" + Task = "(L2) Ensure 'MSS: (DisableSavePassword) Prevent the dial-up password from being saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\RasMan\Parameters" ` + -Name "disablesavepassword" ` + | Select-Object -ExpandProperty "disablesavepassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.5" + Task = "(L1) Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.6" + Task = "(L2) Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "KeepAliveTime" ` + | Select-Object -ExpandProperty "KeepAliveTime" + + if ($regValue -ne 300000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 300000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.7" + Task = "(L1) Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.8" + Task = "(L2) Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "PerformRouterDiscovery" ` + | Select-Object -ExpandProperty "PerformRouterDiscovery" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.9" + Task = "(L1) Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.10" + Task = "(L1) Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScreenSaverGracePeriod" ` + | Select-Object -ExpandProperty "ScreenSaverGracePeriod" + + if ($regValue -notmatch "^[0-5]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[0-5]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.11" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.12" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.13" + Task = "(L1) Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security" ` + -Name "WarningLevel" ` + | Select-Object -ExpandProperty "WarningLevel" + + if (($regValue -gt 90)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 90" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.1" + Task = "(L1) Ensure 'Configure NetBIOS settings' is set to 2 - 'Enabled: Disable NetBIOS name resolution on public networks' (or 0 - Disable NetBIOS name resolution)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableNetbios" ` + | Select-Object -ExpandProperty "EnableNetbios" + + if (($regValue -ne 2) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2 or x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.2" + Task = "(L1) Ensure 'Turn off multicast name resolution' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.5.1" + Task = "(L2) Ensure 'Enable Font Providers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableFontProviders" ` + | Select-Object -ExpandProperty "EnableFontProviders" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.1" + Task = "(L1) Ensure 'Enable insecure guest logons' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 A" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnDomain" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 B" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnPublicNet" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 C" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (EnableLLTDIO)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableLLTDIO" ` + | Select-Object -ExpandProperty "EnableLLTDIO" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 D" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitLLTDIOOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitLLTDIOOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 A" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnDomain" ` + | Select-Object -ExpandProperty "AllowRspndrOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 B" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnPublicNet" ` + | Select-Object -ExpandProperty "AllowRspndrOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 C" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (EnableRspndr)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableRspndr" ` + | Select-Object -ExpandProperty "EnableRspndr" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 D" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitRspndrOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitRspndrOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.10.2" + Task = "(L2) Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Peernet" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.2" + Task = "(L1) Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.3" + Task = "(L1) Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 A" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`" and `"Require Integrity`" set for all NETLOGON and SYSVOL shares' (\\*\NETLOGON)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if ($regValue -eq $null) { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object { $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 B" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`" and `"Require Integrity`" set for all NETLOGON and SYSVOL shares' (\\*\SYSVOL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if ($regValue -eq $null) { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object { $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.19.2.1" + Task = "(L2) Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "DisabledComponents" ` + | Select-Object -ExpandProperty "DisabledComponents" + + if (($regValue -ne 255)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 A" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (EnableRegistrars)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "EnableRegistrars" ` + | Select-Object -ExpandProperty "EnableRegistrars" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 B" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableUPnPRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableUPnPRegistrar" ` + | Select-Object -ExpandProperty "DisableUPnPRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 C" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableInBand802DOT11Registrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableInBand802DOT11Registrar" ` + | Select-Object -ExpandProperty "DisableInBand802DOT11Registrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 D" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableFlashConfigRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableFlashConfigRegistrar" ` + | Select-Object -ExpandProperty "DisableFlashConfigRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 E" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableWPDRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableWPDRegistrar" ` + | Select-Object -ExpandProperty "DisableWPDRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.2" + Task = "(L2) Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\UI" ` + -Name "DisableWcnUi" ` + | Select-Object -ExpandProperty "DisableWcnUi" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.1" + Task = "(L1) Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled: 3 = Prevent Wi-Fi when on Ethernet'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fMinimizeConnections" ` + | Select-Object -ExpandProperty "fMinimizeConnections" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.23.2.1" + Task = "(L1) Ensure 'Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config" ` + -Name "AutoConnectAllowedOEM" ` + | Select-Object -ExpandProperty "AutoConnectAllowedOEM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.1" + Task = "(L1) Ensure 'Allow Print Spooler to accept client connections' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "RegisterSpoolerRemoteRpcEndPoint" ` + | Select-Object -ExpandProperty "RegisterSpoolerRemoteRpcEndPoint" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.2" + Task = "(L1) Ensure 'Configure Redirection Guard' is set to 'Enabled: Redirection Guard Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "RedirectionGuardPolicy" ` + | Select-Object -ExpandProperty "RedirectionGuardPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.3" + Task = "(L1) Ensure 'Configure RPC connection settings: Protocol to use for outgoing RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcUseNamedPipeProtocol" ` + | Select-Object -ExpandProperty "RpcUseNamedPipeProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.4" + Task = "(L1) Ensure 'Configure RPC connection settings: Use authentication for outgoing RPC connections' is set to 'Enabled: Default'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcAuthentication" ` + | Select-Object -ExpandProperty "RpcAuthentication" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.5" + Task = "(L1) Ensure 'Configure RPC listener settings: Protocols to allow for incoming RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcProtocols" ` + | Select-Object -ExpandProperty "RpcProtocols" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.6" + Task = "(L1) Ensure 'Configure RPC listener settings: Authentication protocol to use for incoming RPC connections:' is set to 'Enabled: Negotiate' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "ForceKerberosForRpc" ` + | Select-Object -ExpandProperty "ForceKerberosForRpc" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0 or x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.7" + Task = "(L1) Ensure 'Configure RPC over TCP port' is set to 'Enabled: 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcTcpPort" ` + | Select-Object -ExpandProperty "RpcTcpPort" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.8" + Task = "(L1) Ensure 'Limits print driver installation to Administrators' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "RestrictDriverInstallationToAdministrators" ` + | Select-Object -ExpandProperty "RestrictDriverInstallationToAdministrators" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.9" + Task = "(L1) Ensure 'Manage processing of Queue-specific files' is set to 'Enabled: Limit Queue-specific files to Color profiles'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "CopyFilesPolicy" ` + | Select-Object -ExpandProperty "CopyFilesPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.10" + Task = "(L1) Ensure 'Point and Print Restrictions: When installing drivers for a new connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "NoWarningNoElevationOnInstall" ` + | Select-Object -ExpandProperty "NoWarningNoElevationOnInstall" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.11" + Task = "(L1) Ensure 'Point and Print Restrictions: When updating drivers for an existing connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "UpdatePromptSettings" ` + | Select-Object -ExpandProperty "UpdatePromptSettings" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.1.1" + Task = "(L2) Ensure 'Turn off notifications network usage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.3.1" + Task = "(L1) Ensure 'Include command line in process creation events' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.1" + Task = "(L1) Ensure 'Encryption Oracle Remediation' is set to 'Enabled: Force Updated Clients'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.2" + Task = "(L1) Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.1" + Task = "(NG) Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.2" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Select Platform Security Level' is set to 'Secure Boot' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if (($regValue -ne 1) -and ($regValue -ne 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.3" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Virtualization Based Protection of Code Integrity' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.4" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Require UEFI Memory Attributes Table' is set to 'True (checked)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HVCIMATRequired" ` + | Select-Object -ExpandProperty "HVCIMATRequired" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.5" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.6" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Secure Launch Configuration' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureSystemGuardLaunch" ` + | Select-Object -ExpandProperty "ConfigureSystemGuardLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.1" + Task = "(BL) Ensure 'Prevent installation of devices that match any of these device IDs' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceIDs" ` + | Select-Object -ExpandProperty "DenyDeviceIDs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.2" + Task = "(BL) Ensure 'Prevent installation of devices that match any of these device IDs: Prevent installation of devices that match any of these device IDs' is set to 'PCI\CC_0C0A'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceIDs" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "PCI\CC_0C0A") { + return @{ + Message = "Registry value is '$regValue'. Expected: PCI\CC_0C0A" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.3" + Task = "(BL) Ensure 'Prevent installation of devices that match any of these device IDs: Also apply to matching devices that are already installed.' is set to 'True' (checked)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceIDsRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceIDsRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.4" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClasses" ` + | Select-Object -ExpandProperty "DenyDeviceClasses" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.5 A" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the SBP2 Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "{d48179be-ec20-11d1-b6b8-00c04fa372a7}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {d48179be-ec20-11d1-b6b8-00c04fa372a7}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.5 B" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the IEC-61883 Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "2" ` + | Select-Object -ExpandProperty "2" + + if ($regValue -ne "{7ebefbc0-3200-11d2-b4c2-00a0C9697d07}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {7ebefbc0-3200-11d2-b4c2-00a0C9697d07}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.5 C" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the AVC Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "3" ` + | Select-Object -ExpandProperty "3" + + if ($regValue -ne "{c06ff265-ae09-48f0-812c-16753d7cba83}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {c06ff265-ae09-48f0-812c-16753d7cba83}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.5 D" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 Host Bus Controller Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "4" ` + | Select-Object -ExpandProperty "4" + + if ($regValue -ne "{6bdd1fc1-810f-11d0-bec7-08002be2092f}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {6bdd1fc1-810f-11d0-bec7-08002be2092f}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.6" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Also apply to matching devices that are already installed.' is set to 'True' (checked)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClassesRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceClassesRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.2" + Task = "(L1) Ensure 'Prevent device metadata retrieval from the Internet' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" ` + -Name "PreventDeviceMetadataFromNetwork" ` + | Select-Object -ExpandProperty "PreventDeviceMetadataFromNetwork" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.13.1" + Task = "(L1) Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.2" + Task = "(L1) Ensure 'Continue experiences on this device' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableCdp" ` + | Select-Object -ExpandProperty "EnableCdp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.1" + Task = "(L2) Ensure 'Turn off access to the Store' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoUseStoreOpenWith" ` + | Select-Object -ExpandProperty "NoUseStoreOpenWith" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.2" + Task = "(L1) Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.3" + Task = "(L2) Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TabletPC" ` + -Name "PreventHandwritingDataSharing" ` + | Select-Object -ExpandProperty "PreventHandwritingDataSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.4" + Task = "(L2) Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HandwritingErrorReports" ` + -Name "PreventHandwritingErrorReports" ` + | Select-Object -ExpandProperty "PreventHandwritingErrorReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.5" + Task = "(L2) Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Internet Connection Wizard" ` + -Name "ExitOnMSICW" ` + | Select-Object -ExpandProperty "ExitOnMSICW" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.6" + Task = "(L1) Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.7" + Task = "(L2) Ensure 'Turn off printing over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.8" + Task = "(L2) Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Registration Wizard Control" ` + -Name "NoRegistration" ` + | Select-Object -ExpandProperty "NoRegistration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.9" + Task = "(L2) Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SearchCompanion" ` + -Name "DisableContentFileUpdates" ` + | Select-Object -ExpandProperty "DisableContentFileUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.10" + Task = "(L2) Ensure 'Turn off the `"Order Prints`" picture task' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoOnlinePrintsWizard" ` + | Select-Object -ExpandProperty "NoOnlinePrintsWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.11" + Task = "(L2) Ensure 'Turn off the `"Publish to Web`" task for files and folders' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoPublishingWizard" ` + | Select-Object -ExpandProperty "NoPublishingWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.12" + Task = "(L2) Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Messenger\Client" ` + -Name "CEIP" ` + | Select-Object -ExpandProperty "CEIP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13" + Task = "(L2) Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SQMClient\Windows" ` + -Name "CEIPEnable" ` + | Select-Object -ExpandProperty "CEIPEnable" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.14 A" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (Disabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.14 B" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (DoReport)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\PCHealth\ErrorReporting" ` + -Name "DoReport" ` + | Select-Object -ExpandProperty "DoReport" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 A" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitBehavior)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitBehavior" ` + | Select-Object -ExpandProperty "DevicePKInitBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 B" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitEnabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitEnabled" ` + | Select-Object -ExpandProperty "DevicePKInitEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.1" + Task = "(BL) Ensure 'Enumeration policy for external devices incompatible with Kernel DMA Protection' is set to 'Enabled: Block All'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.1" + Task = "(L1) Ensure 'Configures LSASS to run as a protected process' is set to 'Enabled: Enabled with UEFI Lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "ConfigureLsaProtectedProcess" ` + | Select-Object -ExpandProperty "ConfigureLsaProtectedProcess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.1" + Task = "(L2) Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Control Panel\International" ` + -Name "BlockUserInputMethodsForSignIn" ` + | Select-Object -ExpandProperty "BlockUserInputMethodsForSignIn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.1" + Task = "(L1) Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockUserFromShowingAccountDetailsOnSignin" ` + | Select-Object -ExpandProperty "BlockUserFromShowingAccountDetailsOnSignin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.2" + Task = "(L1) Ensure 'Do not display network selection UI' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.3" + Task = "(L1) Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.4" + Task = "(L1) Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.30.1" + Task = "(L2) Ensure 'Allow Clipboard synchronization across devices' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowCrossDeviceClipboard" ` + | Select-Object -ExpandProperty "AllowCrossDeviceClipboard" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.30.2" + Task = "(L2) Ensure 'Allow upload of User Activities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "UploadUserActivities" ` + | Select-Object -ExpandProperty "UploadUserActivities" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.1" + Task = "(L1) Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.2" + Task = "(L1) Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.3" + Task = "(BL) Ensure 'Allow standby states (S1-S3) when sleeping (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.4" + Task = "(BL) Ensure 'Allow standby states (S1-S3) when sleeping (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.5" + Task = "(L1) Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.6" + Task = "(L1) Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.34.1" + Task = "(L1) Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.34.2" + Task = "(L1) Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.1" + Task = "(L1) Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "EnableAuthEpResolution" ` + | Select-Object -ExpandProperty "EnableAuthEpResolution" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.2" + Task = "(L1) Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.46.5.1" + Task = "(L2) Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.46.11.1" + Task = "(L2) Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d}" ` + -Name "ScenarioExecutionEnabled" ` + | Select-Object -ExpandProperty "ScenarioExecutionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.48.1" + Task = "(L2) Ensure 'Turn off the advertising ID' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" ` + -Name "DisabledByGroupPolicy" ` + | Select-Object -ExpandProperty "DisabledByGroupPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.3.1" + Task = "(L2) Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager" ` + -Name "AllowSharedLocalAppData" ` + | Select-Object -ExpandProperty "AllowSharedLocalAppData" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.3.2" + Task = "(L1) Ensure 'Prevent non-admin users from installing packaged Windows apps' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Appx" ` + -Name "BlockNonAdminUserInstall" ` + | Select-Object -ExpandProperty "BlockNonAdminUserInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.4.1" + Task = "(L1) Ensure 'Let Windows apps activate with voice while the system is locked' is set to 'Enabled: Force Deny'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsActivateWithVoiceAboveLock" ` + | Select-Object -ExpandProperty "LetAppsActivateWithVoiceAboveLock" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.5.1" + Task = "(L1) Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.5.2" + Task = "(L2) Ensure 'Block launching Universal Windows apps with Windows Runtime API access from hosted content.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "BlockHostedAppAccessWinRT" ` + | Select-Object -ExpandProperty "BlockHostedAppAccessWinRT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.1" + Task = "(L1) Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.2" + Task = "(L1) Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.3" + Task = "(L1) Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.8.1.1" + Task = "(L1) Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.1" + Task = "(BL) Ensure 'Allow access to BitLocker-protected fixed data drives from earlier versions of Windows' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVDiscoveryVolumeType" ` + | Select-Object -ExpandProperty "FDVDiscoveryVolumeType" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: This value should be empty." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.2" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecovery" ` + | Select-Object -ExpandProperty "FDVRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Allow data recovery agent' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVManageDRA" ` + | Select-Object -ExpandProperty "FDVManageDRA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Recovery Password' is set to 'Enabled: Allow 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecoveryPassword" ` + | Select-Object -ExpandProperty "FDVRecoveryPassword" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Recovery Key' is set to 'Enabled: Allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecoveryKey" ` + | Select-Object -ExpandProperty "FDVRecoveryKey" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVHideRecoveryPage" ` + | Select-Object -ExpandProperty "FDVHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Save BitLocker recovery information to AD DS for fixed data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "FDVActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Configure storage of BitLocker recovery information to AD DS' is set to 'Enabled: Backup recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "FDVActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for fixed data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "FDVRequireActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.10" + Task = "(BL) Ensure 'Configure use of hardware-based encryption for fixed data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVHardwareEncryption" ` + | Select-Object -ExpandProperty "FDVHardwareEncryption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.11" + Task = "(BL) Ensure 'Configure use of passwords for fixed data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVPassphrase" ` + | Select-Object -ExpandProperty "FDVPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.12" + Task = "(BL) Ensure 'Configure use of smart cards on fixed data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVAllowUserCert" ` + | Select-Object -ExpandProperty "FDVAllowUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.13" + Task = "(BL) Ensure 'Configure use of smart cards on fixed data drives: Require use of smart cards on fixed data drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVEnforceUserCert" ` + | Select-Object -ExpandProperty "FDVEnforceUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.1" + Task = "(BL) Ensure 'Allow enhanced PINs for startup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "UseEnhancedPin" ` + | Select-Object -ExpandProperty "UseEnhancedPin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.2" + Task = "(BL) Ensure 'Allow Secure Boot for integrity validation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "OSAllowSecureBootForIntegrity" ` + | Select-Object -ExpandProperty "OSAllowSecureBootForIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecovery" ` + | Select-Object -ExpandProperty "OSRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Allow data recovery agent' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSManageDRA" ` + | Select-Object -ExpandProperty "OSManageDRA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Recovery Password' is set to 'Enabled: Require 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecoveryPassword" ` + | Select-Object -ExpandProperty "OSRecoveryPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Recovery Key' is set to 'Enabled: Do not allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecoveryKey" ` + | Select-Object -ExpandProperty "OSRecoveryKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSHideRecoveryPage" ` + | Select-Object -ExpandProperty "OSHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Save BitLocker recovery information to AD DS for operating system drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "OSActiveDirectoryBackup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Configure storage of BitLocker recovery information to AD DS:' is set to 'Enabled: Store recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "OSActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.10" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for operating system drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "OSRequireActiveDirectoryBackup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.11" + Task = "(BL) Ensure 'Configure use of hardware-based encryption for operating system drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSHardwareEncryption" ` + | Select-Object -ExpandProperty "OSHardwareEncryption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.12" + Task = "(BL) Ensure 'Configure use of passwords for operating system drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "OSPassphrase" ` + | Select-Object -ExpandProperty "OSPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.13" + Task = "(BL) Ensure 'Require additional authentication at startup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseAdvancedStartup" ` + | Select-Object -ExpandProperty "UseAdvancedStartup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.14" + Task = "(BL) Ensure 'Require additional authentication at startup: Allow BitLocker without a compatible TPM' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "EnableBDEWithNoTPM" ` + | Select-Object -ExpandProperty "EnableBDEWithNoTPM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.15" + Task = "(BL) Ensure 'Require additional authentication at startup: Configure TPM startup:' is set to 'Enabled: Do not allow TPM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPM" ` + | Select-Object -ExpandProperty "UseTPM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.16" + Task = "(BL) Ensure 'Require additional authentication at startup: Configure TPM startup PIN:' is set to 'Enabled: Require startup PIN with TPM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPMPIN" ` + | Select-Object -ExpandProperty "UseTPMPIN" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.17" + Task = "(BL) Ensure 'Require additional authentication at startup: Configure TPM startup key:' is set to 'Enabled: Do not allow startup key with TPM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPMKey" ` + | Select-Object -ExpandProperty "UseTPMKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.18" + Task = "(BL) Ensure 'Require additional authentication at startup: Configure TPM startup key and PIN:' is set to 'Enabled: Do not allow startup key and PIN with TPM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPMKeyPIN" ` + | Select-Object -ExpandProperty "UseTPMKeyPIN" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.1" + Task = "(BL) Ensure 'Allow access to BitLocker-protected removable data drives from earlier versions of Windows' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVDiscoveryVolumeType" ` + | Select-Object -ExpandProperty "RDVDiscoveryVolumeType" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: ''" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.2" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecovery" ` + | Select-Object -ExpandProperty "RDVRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Allow data recovery agent' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVManageDRA" ` + | Select-Object -ExpandProperty "RDVManageDRA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Recovery Password' is set to 'Enabled: Do not allow 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecoveryPassword" ` + | Select-Object -ExpandProperty "RDVRecoveryPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Recovery Key' is set to 'Enabled: Do not allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecoveryKey" ` + | Select-Object -ExpandProperty "RDVRecoveryKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVHideRecoveryPage" ` + | Select-Object -ExpandProperty "RDVHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Save BitLocker recovery information to AD DS for removable data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "RDVActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Configure storage of BitLocker recovery information to AD DS:' is set to 'Enabled: Backup recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "RDVActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for removable data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "RDVRequireActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.10" + Task = "(BL) Ensure 'Configure use of hardware-based encryption for removable data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVHardwareEncryption" ` + | Select-Object -ExpandProperty "RDVHardwareEncryption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.11" + Task = "(BL) Ensure 'Configure use of passwords for removable data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVPassphrase" ` + | Select-Object -ExpandProperty "RDVPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.12" + Task = "(BL) Ensure 'Configure use of smart cards on removable data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVAllowUserCert" ` + | Select-Object -ExpandProperty "RDVAllowUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.13" + Task = "(BL) Ensure 'Configure use of smart cards on removable data drives: Require use of smart cards on removable data drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVEnforceUserCert" ` + | Select-Object -ExpandProperty "RDVEnforceUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.14" + Task = "(BL) Ensure 'Deny write access to removable drives not protected by BitLocker' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\Microsoft\FVE" ` + -Name "RDVDenyWriteAccess" ` + | Select-Object -ExpandProperty "RDVDenyWriteAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.15" + Task = "(BL) Ensure 'Deny write access to removable drives not protected by BitLocker: Do not allow write access to devices configured in another organization' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVDenyCrossOrg" ` + | Select-Object -ExpandProperty "RDVDenyCrossOrg" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.4" + Task = "(BL) Ensure 'Disable new DMA devices when this computer is locked' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "DisableExternalDMAUnderLock" ` + | Select-Object -ExpandProperty "DisableExternalDMAUnderLock" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1" + Task = "(L2) Ensure 'Allow Use of Camera' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera" ` + -Name "AllowCamera" ` + | Select-Object -ExpandProperty "AllowCamera" + + if ($regValue -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam" ` + -Name "Value" ` + | Select-Object -ExpandProperty "Value" + + if ($regValue -match "Deny") { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Camera is not deactivated." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "18.10.12.1" + Task = "(L1) Ensure 'Turn off cloud consumer account state content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableConsumerAccountStateContent" ` + | Select-Object -ExpandProperty "DisableConsumerAccountStateContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.12.2" + Task = "(L2) Ensure 'Turn off cloud optimized content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableCloudOptimizedContent" ` + | Select-Object -ExpandProperty "DisableCloudOptimizedContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.12.3" + Task = "(L1) Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.13.1" + Task = "(L1) Ensure 'Require pin for pairing' is set to 'Enabled: First Time' OR 'Enabled: Always'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect" ` + -Name "RequirePinForPairing" ` + | Select-Object -ExpandProperty "RequirePinForPairing" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.1" + Task = "(L1) Ensure 'Do not display the password reveal button' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.2" + Task = "(L1) Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.3" + Task = "(L1) Ensure 'Prevent the use of security questions for local accounts' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "NoLocalPasswordResetQuestions" ` + | Select-Object -ExpandProperty "NoLocalPasswordResetQuestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.1" + Task = "(L1) Ensure 'Allow Diagnostic Data' is set to '0 - Enabled: Diagnostic data off (not recommended)' or '1 - Enabled: Send required diagnostic data'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0 or x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.2" + Task = "(L2) Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableEnterpriseAuthProxy" ` + | Select-Object -ExpandProperty "DisableEnterpriseAuthProxy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.3" + Task = "(L1) Ensure 'Disable OneSettings Downloads' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableOneSettingsDownloads" ` + | Select-Object -ExpandProperty "DisableOneSettingsDownloads" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.4" + Task = "(L1) Ensure 'Do not show feedback notifications' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DoNotShowFeedbackNotifications" ` + | Select-Object -ExpandProperty "DoNotShowFeedbackNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.5" + Task = "(L1) Ensure 'Enable OneSettings Auditing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "EnableOneSettingsAuditing" ` + | Select-Object -ExpandProperty "EnableOneSettingsAuditing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.6" + Task = "(L1) Ensure 'Limit Diagnostic Log Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDiagnosticLogCollection" ` + | Select-Object -ExpandProperty "LimitDiagnosticLogCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.7" + Task = "(L1) Ensure 'Limit Dump Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDumpCollection" ` + | Select-Object -ExpandProperty "LimitDumpCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.8" + Task = "(L1) Ensure 'Toggle user control over Insider builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" ` + -Name "AllowBuildPreview" ` + | Select-Object -ExpandProperty "AllowBuildPreview" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.1" + Task = "(L1) Ensure 'Download Mode' is NOT set to 'Enabled: Internet'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeliveryOptimization" ` + -Name "DODownloadMode" ` + | Select-Object -ExpandProperty "DODownloadMode" + + if (($regValue -eq 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x != 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.1" + Task = "(L1) Ensure 'Enable App Installer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableAppInstaller" ` + | Select-Object -ExpandProperty "EnableAppInstaller" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.2" + Task = "(L1) Ensure 'Enable App Installer Experimental Features' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableExperimentalFeatures" ` + | Select-Object -ExpandProperty "EnableExperimentalFeatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.3" + Task = "(L1) Ensure 'Enable App Installer Hash Override' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableHashOverride" ` + | Select-Object -ExpandProperty "EnableHashOverride" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.4" + Task = "(L1) Ensure 'Enable App Installer ms-appinstaller protocol' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableMSAppInstallerProtocol" ` + | Select-Object -ExpandProperty "EnableMSAppInstallerProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.1.1" + Task = "(L1) Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.1.2" + Task = "(L1) Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.2.1" + Task = "(L1) Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.2.2" + Task = "(L1) Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 196608)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.3.1" + Task = "(L1) Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.3.2" + Task = "(L1) Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.4.1" + Task = "(L1) Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.4.2" + Task = "(L1) Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.2" + Task = "(L1) Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.3" + Task = "(L1) Ensure 'Turn off heap termination on corruption' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.4" + Task = "(L1) Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.33.1" + Task = "(L1) Ensure 'Prevent the computer from joining a homegroup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HomeGroup" ` + -Name "DisableHomeGroup" ` + | Select-Object -ExpandProperty "DisableHomeGroup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.35.1" + Task = "(L1) 'Disable Internet Explorer 11 as a standalone browser' is set to 'Enabled: Always'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Main" ` + -Name "NotifyDisableIEOptions" ` + | Select-Object -ExpandProperty "NotifyDisableIEOptions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.37.1" + Task = "(L2) Ensure 'Turn off location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.41.1" + Task = "(L2) Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging" ` + -Name "AllowMessageSync" ` + | Select-Object -ExpandProperty "AllowMessageSync" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.1" + Task = "(L1) Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount" ` + -Name "DisableUserAuth" ` + | Select-Object -ExpandProperty "DisableUserAuth" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.5.1" + Task = "(L1) Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.5.2" + Task = "(L2) Ensure 'Join Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.1" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 A" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office communication application from creating child processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 B" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating executable content'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 D" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block execution of potentially obfuscated scripts'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 E" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from injecting code into other processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 F" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Adobe Reader from creating child processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 G" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Win32 API calls from Office macro'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 H" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block credential stealing from the Windows local security authority subsystem (lsass.exe)'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 I" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block untrusted and unsigned processes that run from USB'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 J" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block executable content from email client and webmail'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 K" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block JavaScript or VBScript from launching downloaded executable content'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 L" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating child processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 M" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block persistence through WMI event subscription'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.3.1" + Task = "(L1) Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.7.1" + Task = "(L2) Ensure 'Enable file hash computation feature' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\MpEngine" ` + -Name "EnableFileHashComputation" ` + | Select-Object -ExpandProperty "EnableFileHashComputation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.1" + Task = "(L1) Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.2" + Task = "(L1) Ensure 'Turn off real-time protection' is set to 'Disabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.3" + Task = "(L1) Ensure 'Turn on behavior monitoring' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.4" + Task = "(L1) Ensure 'Turn on script scanning' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableScriptScanning" ` + | Select-Object -ExpandProperty "DisableScriptScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.12.1" + Task = "(L2) Ensure 'Configure Watson events' is set to 'Disabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" ` + -Name "DisableGenericReports" ` + | Select-Object -ExpandProperty "DisableGenericReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.1" + Task = "(L1) Ensure 'Scan removable drives' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.2" + Task = "(L1) Ensure 'Turn on e-mail scanning' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.16" + Task = "(L1) Ensure 'Configure detection for potentially unwanted applications' is set to 'Enabled: Block'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.17" + Task = "(L1) Ensure 'Turn off Microsoft Defender AntiVirus' is set to 'Disabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "DisableAntiSpyware" ` + | Select-Object -ExpandProperty "DisableAntiSpyware" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.1" + Task = "(NG) Ensure 'Allow auditing events in Microsoft Defender Application Guard' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AuditApplicationGuard" ` + | Select-Object -ExpandProperty "AuditApplicationGuard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.2" + Task = "(NG) Ensure 'Allow camera and microphone access in Microsoft Defender Application Guard' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowCameraMicrophoneRedirection" ` + | Select-Object -ExpandProperty "AllowCameraMicrophoneRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.3" + Task = "(NG) Ensure 'Allow data persistence for Microsoft Defender Application Guard' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowPersistence" ` + | Select-Object -ExpandProperty "AllowPersistence" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.4" + Task = "(NG) Ensure 'Allow files to download and save to the host operating system from Microsoft Defender Application Guard' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "SaveFilesToHost" ` + | Select-Object -ExpandProperty "SaveFilesToHost" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.5" + Task = "(NG) Ensure 'Configure Windows Defender Application Guard clipboard settings: Clipboard behavior setting' is set to 'Enabled: Enable clipboard operation from an isolated session to the host'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AppHVSIClipboardSettings" ` + | Select-Object -ExpandProperty "AppHVSIClipboardSettings" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.6" + Task = "(NG) Ensure 'Turn on Microsoft Defender Application Guard in Managed Mode' is set to 'Enabled: 1'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowAppHVSI_ProviderSet" ` + | Select-Object -ExpandProperty "AllowAppHVSI_ProviderSet" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.50.1" + Task = "(L2) Ensure 'Enable news and interests on the taskbar' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Feeds" ` + -Name "EnableFeeds" ` + | Select-Object -ExpandProperty "EnableFeeds" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.51.1" + Task = "(L1) Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.1" + Task = "(L2) Ensure 'Turn off Push To Install service' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall" ` + -Name "DisablePushToInstall" ` + | Select-Object -ExpandProperty "DisablePushToInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.2.2" + Task = "(L1) Ensure 'Do not allow passwords to be saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.2.1" + Task = "(L2) Ensure 'Allow users to connect remotely by using Remote Desktop Services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDenyTSConnections" ` + | Select-Object -ExpandProperty "fDenyTSConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.1" + Task = "(L2) Ensure 'Allow UI Automation redirection' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "EnableUiaRedirection" ` + | Select-Object -ExpandProperty "EnableUiaRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.2" + Task = "(L2) Ensure 'Do not allow COM port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCcm" ` + | Select-Object -ExpandProperty "fDisableCcm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.3" + Task = "(L1) Ensure 'Do not allow drive redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.4" + Task = "(L2) Ensure 'Do not allow location redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLocationRedir" ` + | Select-Object -ExpandProperty "fDisableLocationRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.5" + Task = "(L2) Ensure 'Do not allow LPT port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLPT" ` + | Select-Object -ExpandProperty "fDisableLPT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.6" + Task = "(L2) Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisablePNPRedir" ` + | Select-Object -ExpandProperty "fDisablePNPRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.7" + Task = "(L2) Ensure 'Do not allow WebAuthn redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableWebAuthn" ` + | Select-Object -ExpandProperty "fDisableWebAuthn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.1" + Task = "(L1) Ensure 'Always prompt for password upon connection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.2" + Task = "(L1) Ensure 'Require secure RPC communication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.3" + Task = "(L1) Ensure 'Require use of specific security layer for remote (RDP) connections' is set to 'Enabled: SSL'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SecurityLayer" ` + | Select-Object -ExpandProperty "SecurityLayer" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.4" + Task = "(L1) Ensure 'Require user authentication for remote connections by using Network Level Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "UserAuthentication" ` + | Select-Object -ExpandProperty "UserAuthentication" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.5" + Task = "(L1) Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.10.1" + Task = "(L2) Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less, but not Never (0)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxIdleTime" ` + | Select-Object -ExpandProperty "MaxIdleTime" + + if (($regValue -gt 900000 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900000 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.10.2" + Task = "(L2) Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxDisconnectionTime" ` + | Select-Object -ExpandProperty "MaxDisconnectionTime" + + if ($regValue -ne 60000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 60000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.11.1" + Task = "(L1) Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.1" + Task = "(L1) Ensure 'Prevent downloading of enclosures' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.2" + Task = "(L2) Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCloudSearch" ` + | Select-Object -ExpandProperty "AllowCloudSearch" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.3" + Task = "(L1) Ensure 'Allow Cortana' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCortana" ` + | Select-Object -ExpandProperty "AllowCortana" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.4" + Task = "(L1) Ensure 'Allow Cortana above lock screen' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCortanaAboveLock" ` + | Select-Object -ExpandProperty "AllowCortanaAboveLock" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.5" + Task = "(L1) Ensure 'Allow indexing of encrypted files' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.6" + Task = "(L1) Ensure 'Allow search and Cortana to use location' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowSearchToUseLocation" ` + | Select-Object -ExpandProperty "AllowSearchToUseLocation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.7" + Task = "(L2) Ensure 'Allow search highlights' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "EnableDynamicContentInWSB" ` + | Select-Object -ExpandProperty "EnableDynamicContentInWSB" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.63.1" + Task = "(L2) Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" ` + -Name "NoGenTicket" ` + | Select-Object -ExpandProperty "NoGenTicket" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.1" + Task = "(L2) Ensure 'Disable all apps from Microsoft Store' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "DisableStoreApps" ` + | Select-Object -ExpandProperty "DisableStoreApps" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.2" + Task = "(L1) Ensure 'Only display the private store within the Microsoft Store' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "RequirePrivateStoreOnly" ` + | Select-Object -ExpandProperty "RequirePrivateStoreOnly" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.3" + Task = "(L1) Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "AutoDownload" ` + | Select-Object -ExpandProperty "AutoDownload" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.4" + Task = "(L1) Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "DisableOSUpgrade" ` + | Select-Object -ExpandProperty "DisableOSUpgrade" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.5" + Task = "(L2) Ensure 'Turn off the Store application' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "RemoveWindowsStore" ` + | Select-Object -ExpandProperty "RemoveWindowsStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.72.1" + Task = "(L1) Ensure 'Allow widgets' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Dsh" ` + -Name "AllowNewsAndInterests" ` + | Select-Object -ExpandProperty "AllowNewsAndInterests" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.2.1 A" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (EnableSmartScreen)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.2.1 B" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (ShellSmartScreenLevel)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.3.1" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.3.2" + Task = "(L1) Ensure 'Prevent bypassing Windows Defender SmartScreen prompts for sites' is set to 'Enabled' (PreventOverride)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.78.1" + Task = "(L1) Ensure 'Enables or disables Windows Game Recording and Broadcasting' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR" ` + -Name "AllowGameDVR" ` + | Select-Object -ExpandProperty "AllowGameDVR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.1" + Task = "(L2) Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowSuggestedAppsInWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowSuggestedAppsInWindowsInkWorkspace" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.2" + Task = "(L1) Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Enabled: Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if (($regValue -ne 1) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.1" + Task = "(L1) Ensure 'Allow user control over installs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.2" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.3" + Task = "(L2) Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.82.1" + Task = "(L1) Ensure 'Enable MPR notifications for the system' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableMPR" ` + | Select-Object -ExpandProperty "EnableMPR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.82.2" + Task = "(L1) Ensure 'Sign-in and lock last interactive user automatically after a restart' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.87.1" + Task = "(L1) Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.87.2" + Task = "(L1) Ensure 'Turn on PowerShell Transcription' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" ` + -Name "EnableTranscripting" ` + | Select-Object -ExpandProperty "EnableTranscripting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.2" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.3" + Task = "(L1) Ensure 'Disallow Digest authentication' is set to 'Enabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.2" + Task = "(L2) Ensure 'Allow remote server management through WinRM' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowAutoConfig" ` + | Select-Object -ExpandProperty "AllowAutoConfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.3" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.4" + Task = "(L1) Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.90.1" + Task = "(L2) Ensure 'Allow Remote Shell Access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service\WinRS" ` + -Name "AllowRemoteShellAccess" ` + | Select-Object -ExpandProperty "AllowRemoteShellAccess" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.91.1" + Task = "(L1) Ensure 'Allow clipboard sharing with Windows Sandbox' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Sandbox" ` + -Name "AllowClipboardRedirection" ` + | Select-Object -ExpandProperty "AllowClipboardRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.91.2" + Task = "(L1) Ensure 'Allow networking in Windows Sandbox' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Sandbox" ` + -Name "AllowNetworking" ` + | Select-Object -ExpandProperty "AllowNetworking" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.1" + Task = "(L1) Ensure 'Prevent users from modifying settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection" ` + -Name "DisallowExploitProtectionOverride" ` + | Select-Object -ExpandProperty "DisallowExploitProtectionOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.1.1" + Task = "(L1) Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.1" + Task = "(L1) Ensure 'Configure Automatic Updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.2" + Task = "(L1) Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.3" + Task = "(L1) Ensure 'Remove access to `"Pause updates`" feature' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "SetDisablePauseUXAccess" ` + | Select-Object -ExpandProperty "SetDisablePauseUXAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.1" + Task = "(L1) Ensure 'Manage preview builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "ManagePreviewBuildsPolicyValue" ` + | Select-Object -ExpandProperty "ManagePreviewBuildsPolicyValue" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.2 A" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdates" ` + | Select-Object -ExpandProperty "DeferFeatureUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.2 B" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferFeatureUpdatesPeriodInDays" + + if (($regValue -lt 180 -or $regValue -gt 365)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 180 and x <= 365" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.3 A" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdates" ` + | Select-Object -ExpandProperty "DeferQualityUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.3 B" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferQualityUpdatesPeriodInDays" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.1.3.1" + Task = "(L1) Ensure 'Enable screen saver' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaveActive" ` + | Select-Object -ExpandProperty "ScreenSaveActive" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.1.3.2" + Task = "(L1) Ensure 'Password protect the screen saver' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaverIsSecure" ` + | Select-Object -ExpandProperty "ScreenSaverIsSecure" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.5.1.1" + Task = "(L1) Ensure 'Turn off toast notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.6.6.1.1" + Task = "(L2) Ensure 'Turn off Help Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Assistance\Client\1.0" ` + -Name "NoImplicitFeedback" ` + | Select-Object -ExpandProperty "NoImplicitFeedback" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.4.1" + Task = "(L1) Ensure 'Do not preserve zone information in file attachments' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.4.2" + Task = "(L1) Ensure 'Notify antivirus programs when opening attachments' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "ScanWithAntiVirus" ` + | Select-Object -ExpandProperty "ScanWithAntiVirus" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.7.1" + Task = "(L1) Ensure 'Configure Windows spotlight on lock screen' is set to Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "ConfigureWindowsSpotlight" ` + | Select-Object -ExpandProperty "ConfigureWindowsSpotlight" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.7.2" + Task = "(L1) Ensure 'Do not suggest third-party content in Windows spotlight' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.7.3" + Task = "(L2) Ensure 'Do not use diagnostic data for tailored experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableTailoredExperiencesWithDiagnosticData" ` + | Select-Object -ExpandProperty "DisableTailoredExperiencesWithDiagnosticData" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.7.4" + Task = "(L2) Ensure 'Turn off all Windows spotlight features' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsSpotlightFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsSpotlightFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.7.5" + Task = "(L1) Ensure 'Turn off Spotlight collection on Desktop' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableSpotlightCollectionOnDesktop" ` + | Select-Object -ExpandProperty "DisableSpotlightCollectionOnDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.25.1" + Task = "(L1) Ensure 'Prevent users from sharing files within their profile.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInplaceSharing" ` + | Select-Object -ExpandProperty "NoInplaceSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.40.1" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled' (AlwaysInstallElevated)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.42.2.1" + Task = "(L2) Ensure 'Prevent Codec Download' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\WindowsMediaPlayer" ` + -Name "PreventCodecDownload" ` + | Select-Object -ExpandProperty "PreventCodecDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#SecurityOptions.ps1 new file mode 100644 index 0000000..55176b4 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#SecurityOptions.ps1 @@ -0,0 +1,130 @@ +[AuditTest] @{ + Id = "2.3.1.2" + Task = "(L1) Ensure 'Accounts: Guest account status' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.4" + Task = "(L1) Configure 'Accounts: Rename administrator account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?!.*\bAdministrator\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.5" + Task = "(L1) Configure 'Accounts: Rename guest account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.1" + Task = "(L1) Ensure 'Network access: Allow anonymous SID/Name translation' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.6" + Task = "(L1) Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["ForceLogoffWhenHourExpire"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 1) { + return @{ + Message = "'ForceLogoffWhenHourExpire' currently set to: $setOption. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#UserRights.ps1 new file mode 100644 index 0000000..d425e62 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 10-Stand-alone-CIS-2.0.0#UserRights.ps1 @@ -0,0 +1,1312 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "2.2.1" + Task = "(L1) Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Remote Desktop Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.3" + Task = "(L1) Ensure 'Act as part of the operating system' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.4" + Task = "(L1) Ensure 'Adjust memory quotas for a process' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseQuotaPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeIncreaseQuotaPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.5" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.6" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators, Remote Desktop Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.7" + Task = "(L1) Ensure 'Back up files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.8" + Task = "(L1) Ensure 'Change the system time' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemtimePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeSystemtimePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.9" + Task = "(L1) Ensure 'Change the time zone' is set to 'Administrators, LOCAL SERVICE, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTimeZonePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeTimeZonePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.10" + Task = "(L1) Ensure 'Create a pagefile' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.11" + Task = "(L1) Ensure 'Create a token object' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.12" + Task = "(L1) Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.13" + Task = "(L1) Ensure 'Create permanent shared objects' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if($hyperVStatus -ne "Enabled"){ + [AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Configure 'Create symbolic links' [Hyper-V-Feature NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else{ + [AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Configure 'Create symbolic links' [Hyper-V-Feature installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.15" + Task = "(L1) Ensure 'Debug programs' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.16" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.17" + Task = "(L1) Ensure 'Deny log on as a batch job' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.18" + Task = "(L1) Ensure 'Deny log on as a service' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyServiceLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Deny log on locally' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.20" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.21" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @() | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.22" + Task = "(L1) Ensure 'Force shutdown from a remote system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.23" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.24" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.25" + Task = "(L1) Ensure 'Increase scheduling priority' is set to 'Administrators, Window Manager\Window Manager Group'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseBasePriorityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-90-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeIncreaseBasePriorityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.26" + Task = "(L1) Ensure 'Load and unload device drivers' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.27" + Task = "(L1) Ensure 'Lock pages in memory' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.28" + Task = "(L2) Ensure 'Log on as a batch job' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeBatchLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if($hyperVStatus -ne "Enabled"){ + [AuditTest] @{ + Id = "2.2.29" + Task = "(L2) Configure 'Log on as a service' [Hyper-V-Feature NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeServiceLogonRight"] + $identityAccounts = @() | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeServiceLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else{ + [AuditTest] @{ + Id = "2.2.29" + Task = "(L2) Configure 'Log on as a service' [Hyper-V-Feature installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeServiceLogonRight"] + $identityAccounts = @( + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeServiceLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.30" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.31" + Task = "(L1) Ensure 'Modify an object label' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRelabelPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRelabelPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.32" + Task = "(L1) Ensure 'Modify firmware environment values' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.33" + Task = "(L1) Ensure 'Perform volume maintenance tasks' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.34" + Task = "(L1) Ensure 'Profile single process' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.35" + Task = "(L1) Ensure 'Profile system performance' is set to 'Administrators, NT SERVICE\WdiServiceHost'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemProfilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeSystemProfilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.36" + Task = "(L1) Ensure 'Replace a process level token' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAssignPrimaryTokenPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeAssignPrimaryTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.37" + Task = "(L1) Ensure 'Restore files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.38" + Task = "(L1) Ensure 'Shut down the system' is set to 'Administrators, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.39" + Task = "(L1) Ensure 'Take ownership of files or other objects' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#AccountPolicies.ps1 new file mode 100644 index 0000000..212808c --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#AccountPolicies.ps1 @@ -0,0 +1,284 @@ +[AuditTest] @{ + Id = "1.1.1" + Task = "(L1) Ensure 'Enforce password history' is set to '24 or more password(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "(L1) Ensure 'Maximum password age' is set to '365 or fewer days, but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 365 -or $setPolicy -le 0)) { + if ($setPolicy -eq -1) { + #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 365 days and x > 0 days" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "(L1) Ensure 'Minimum password age' is set to '1 or more day(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 1)) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1 days" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "(L1) Ensure 'Minimum password length' is set to '14 or more character(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.5" + Task = "(L1) Ensure 'Password must meet complexity requirements' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.7" + Task = "(L1) Ensure 'Store passwords using reversible encryption' is set to 'Disabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "(L1) Ensure 'Account lockout duration' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15 -or $setPolicy -gt 99999)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15 minutes and x <= 99999 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "(L1) Ensure 'Account lockout threshold' is set to '5 or fewer invalid logon attempt(s), but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 5 -or $setPolicy -le 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 5 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.3" + Task = "(L1) Ensure 'Allow Administrator account lockout' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["AllowAdministratorLockout"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'AllowAdministratorLockout' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.4" + Task = "(L1) Ensure 'Reset account lockout counter after' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 99999 -or $setPolicy -lt 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x <= 99999 minutes and x >= 15 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#AuditPolicies.ps1 new file mode 100644 index 0000000..25e8dd5 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#AuditPolicies.ps1 @@ -0,0 +1,1616 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "17.1.1" + Task = "(L1) Ensure 'Audit Credential Validation' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.1" + Task = "(L1) Ensure 'Audit Application Group Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Application Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Application Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Application Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.2" + Task = "(L1) Ensure 'Audit Security Group Management' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.3" + Task = "(L1) Ensure 'Audit User Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.1" + Task = "(L1) Ensure 'Audit PNP Activity' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.2" + Task = "(L1) Ensure 'Audit Process Creation' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.1" + Task = "(L1) Ensure 'Audit Account Lockout' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.2" + Task = "(L1) Ensure 'Audit Group Membership' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.3" + Task = "(L1) Ensure 'Audit Logoff' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.4" + Task = "(L1) Ensure 'Audit Logon' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.5" + Task = "(L1) Ensure 'Audit Other Logon/Logoff Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.6" + Task = "(L1) Ensure 'Audit Special Logon' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.1" + Task = "(L1) Ensure 'Audit Detailed File Share' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.2" + Task = "(L1) Ensure 'Audit File Share' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.3" + Task = "(L1) Ensure 'Audit Other Object Access Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.4" + Task = "(L1) Ensure 'Audit Removable Storage' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.1" + Task = "(L1) Ensure 'Audit Audit Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.2" + Task = "(L1) Ensure 'Audit Authentication Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.3" + Task = "(L1) Ensure 'Audit Authorization Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.4" + Task = "(L1) Ensure 'Audit MPSSVC Rule-Level Policy Change' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Mpssvc Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Mpssvc Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Mpssvc Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.5" + Task = "(L1) Ensure 'Audit Other Policy Change Events' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.8.1" + Task = "(L1) Ensure 'Audit Sensitive Privilege Use' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.1" + Task = "(L1) Ensure 'Audit IPsec Driver' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Ipsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Ipsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Ipsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.2" + Task = "(L1) Ensure 'Audit Other System Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.3" + Task = "(L1) Ensure 'Audit Security State Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.4" + Task = "(L1) Ensure 'Audit Security System Extension' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.5" + Task = "(L1) Ensure 'Audit System Integrity' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#RegistrySettings.ps1 new file mode 100644 index 0000000..6e82451 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#RegistrySettings.ps1 @@ -0,0 +1,18823 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$avstatus = CheckForActiveAV +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "1.1.6" + Task = "(L1) Ensure 'Relax minimum password length limits' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SAM" ` + -Name "RelaxMinimumPasswordLengthLimits" ` + | Select-Object -ExpandProperty "RelaxMinimumPasswordLengthLimits" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.2" + Task = "(L1) Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.1" + Task = "(L1) Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.2" + Task = "(L1) Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "CrashOnAuditFail" ` + | Select-Object -ExpandProperty "CrashOnAuditFail" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4.1" + Task = "(L2) Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.1" + Task = "(L1) Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.2" + Task = "(L1) Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.3" + Task = "(L1) Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.4" + Task = "(L1) Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.5" + Task = "(L1) Ensure 'Domain member: Maximum machine account password age' is set to '30 or fewer days, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if (($regValue -le 0 -or $regValue -gt 30)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x > 0 and x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.6" + Task = "(L1) Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.1" + Task = "(L1) Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.2" + Task = "(L1) Ensure 'Interactive logon: Don't display last signed-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.3" + Task = "(BL) Ensure 'Interactive logon: Machine account lockout threshold' is set to '10 or fewer invalid logon attempts, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MaxDevicePasswordFailedAttempts" ` + | Select-Object -ExpandProperty "MaxDevicePasswordFailedAttempts" + + if (($regValue -gt 10 -or $regValue -le 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 10 and x > 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.4" + Task = "(L1) Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.5" + Task = "(L1) Configure 'Interactive logon: Message text for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.6" + Task = "(L1) Configure 'Interactive logon: Message title for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.7" + Task = "(L2) Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "CachedLogonsCount" ` + | Select-Object -ExpandProperty "CachedLogonsCount" + + if ($regValue -notmatch "^[43210]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[43210]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.8" + Task = "(L1) Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if (($regValue -gt 14 -or $regValue -lt 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 14 and x >= 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.9" + Task = "(L1) Ensure 'Interactive logon: Smart card removal behavior' is set to 1 - 'Lock Workstation' or 2 / 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -notmatch "^(1|2|3)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(1|2|3)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.8.1" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.2" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True) { + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.3" + Task = "(L1) Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.1" + Task = "(L1) Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if (($regValue -gt 15)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.2" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.3" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True) { + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.4" + Task = "(L1) Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "enableforcedlogoff" ` + | Select-Object -ExpandProperty "enableforcedlogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.5" + Task = "(L1) Ensure 'Microsoft network server: Server SPN target name validation level' is set to 1 - 'Accept if provided by client' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "SMBServerNameHardeningLevel" ` + | Select-Object -ExpandProperty "SMBServerNameHardeningLevel" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.2" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.3" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.4" + Task = "(L1) Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.5" + Task = "(L1) Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.6" + Task = "(L1) Ensure 'Network access: Named Pipes that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.7" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\ProductOptions" + "System\CurrentControlSet\Control\Server Applications" + "Software\Microsoft\Windows NT\CurrentVersion" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\ProductOptions System\CurrentControlSet\Control\Server Applications Software\Microsoft\Windows NT\CurrentVersion" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.8" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9" + Task = "(L1) Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.10" + Task = "(L1) Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "restrictremotesam" ` + | Select-Object -ExpandProperty "restrictremotesam" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.11" + Task = "(L1) Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionShares" ` + | Select-Object -ExpandProperty "NullSessionShares" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.12" + Task = "(L1) Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.1" + Task = "(L1) Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.2" + Task = "(L1) Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.3" + Task = "(L1) Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.4" + Task = "(L1) Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.5" + Task = "(L1) Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.7" + Task = "(L1) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.8" + Task = "(L1) Ensure 'Network security: LDAP client encryption requirements' is set to 1 - 'Negotiate sealing' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LDAP" ` + -Name "ldapclientconfidentiality" ` + | Select-Object -ExpandProperty "ldapclientconfidentiality" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.9" + Task = "(L1) Ensure 'Network security: LDAP client signing requirements' is set to 1 - 'Negotiate signing' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.10" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.11" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.12" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Audit Incoming NTLM Traffic' is set to 'Enable auditing for all accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AuditReceivingNTLMTraffic" ` + | Select-Object -ExpandProperty "AuditReceivingNTLMTraffic" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.13" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers' is set to 1 - 'Audit all' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "RestrictSendingNTLMTraffic" ` + | Select-Object -ExpandProperty "RestrictSendingNTLMTraffic" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.14.1" + Task = "(L2) Ensure 'System cryptography: Force strong key protection for user keys stored on the computer' is set to 1 - 'User is prompted when the key is first used' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography" ` + -Name "ForceKeyProtection" ` + | Select-Object -ExpandProperty "ForceKeyProtection" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.1" + Task = "(L1) Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.2" + Task = "(L1) Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.1" + Task = "(L1) Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.2" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 2 - 'Prompt for consent on the secure desktop' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.3" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.4" + Task = "(L1) Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.5" + Task = "(L1) Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.6" + Task = "(L1) Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.7" + Task = "(L1) Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.8" + Task = "(L1) Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1" + Task = "(L2) Ensure 'Bluetooth Audio Gateway Service (BTAGService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTAGService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2" + Task = "(L2) Ensure 'Bluetooth Support Service (bthserv)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bthserv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.3" + Task = "(L1) Ensure 'Computer Browser (Browser)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.4" + Task = "(L2) Ensure 'Downloaded Maps Manager (MapsBroker)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MapsBroker" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.5" + Task = "(L2) Ensure 'GameInput Service (GameInputSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\GameInputSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.6" + Task = "(L2) Ensure 'Geolocation Service (lfsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lfsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.7" + Task = "(L1) Ensure 'IIS Admin Service (IISADMIN)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IISADMIN" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.8" + Task = "(L1) Ensure 'Infrared monitor service (irmon)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\irmon" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.9" + Task = "(L2) Ensure 'Link-Layer Topology Discovery Mapper (lltdsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lltdsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.10" + Task = "(L1) Ensure 'LxssManager (LxssManager)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LxssManager" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.11" + Task = "(L1) Ensure 'Microsoft FTP Service (FTPSVC)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FTPSVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.12" + Task = "(L2) Ensure 'Microsoft iSCSI Initiator Service (MSiSCSI)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSiSCSI" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.13" + Task = "(L1) Ensure 'OpenSSH SSH Server (sshd)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sshd" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.14" + Task = "(L2) Ensure 'Print Spooler (Spooler)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.15" + Task = "(L2) Ensure 'Problem Reports and Solutions Control Panel Support (wercplsupport)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wercplsupport" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.16" + Task = "(L2) Ensure 'Remote Access Auto Connection Manager (RasAuto)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasAuto" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.17" + Task = "(L2) Ensure 'Remote Desktop Configuration (SessionEnv)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SessionEnv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.18" + Task = "(L2) Ensure 'Remote Desktop Services (TermService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.19" + Task = "(L2) Ensure 'Remote Desktop Services UserMode Port Redirector (UmRdpService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UmRdpService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.20" + Task = "(L1) Ensure 'Remote Procedure Call (RPC) Locator (RpcLocator)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcLocator" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.21" + Task = "(L2) Ensure 'Remote Registry (RemoteRegistry)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteRegistry" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.22" + Task = "(L1) Ensure 'Routing and Remote Access (RemoteAccess)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.23" + Task = "(L2) Ensure 'Server (LanmanServer)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.24" + Task = "(L1) Ensure 'Simple TCP/IP Services (simptcp)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\simptcp" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.25" + Task = "(L2) Ensure 'SNMP Service (SNMP)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SNMP" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.26" + Task = "(L1) Ensure 'Special Administration Console Helper (sacsvr)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sacsvr" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.27" + Task = "(L1) Ensure 'SSDP Discovery (SSDPSRV)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SSDPSRV" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.28" + Task = "(L1) Ensure 'UPnP Device Host (upnphost)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\upnphost" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.29" + Task = "(L1) Ensure 'Web Management Service (WMSvc)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.30" + Task = "(L2) Ensure 'Windows Error Reporting Service (WerSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WerSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.31" + Task = "(L2) Ensure 'Windows Event Collector (Wecsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Wecsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.32" + Task = "(L1) Ensure 'Windows Media Player Network Sharing Service (WMPNetworkSvc)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMPNetworkSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.33" + Task = "(L1) Ensure 'Windows Mobile Hotspot Service (icssvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\icssvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.34" + Task = "(L2) Ensure 'Windows Push Notifications System Service (WpnService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WpnService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.35" + Task = "(L2) Ensure 'Windows PushToInstall Service (PushToInstall)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PushToInstall" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.36" + Task = "(L2) Ensure 'Windows Remote Management (WS-Management) (WinRM)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinRM" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.37" + Task = "(L2) Ensure 'WinHTTP Web Proxy Auto-Discovery Service (WinHttpAutoProxySvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinHttpAutoProxySvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.38" + Task = "(L1) Ensure 'World Wide Web Publishing Service (W3SVC)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.39" + Task = "(L1) Ensure 'Xbox Accessory Management Service (XboxGipSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxGipSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.40" + Task = "(L1) Ensure 'Xbox Live Auth Manager (XblAuthManager)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblAuthManager" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.41" + Task = "(L1) Ensure 'Xbox Live Game Save (XblGameSave)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblGameSave" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.42" + Task = "(L1) Ensure 'Xbox Live Networking Service (XboxNetApiSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxNetApiSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.1.1" + Task = "(L1) Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.2" + Task = "(L1) Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.3" + Task = "(L1) Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.4" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\domainfw.log'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\domainfw.log"; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.5" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.6" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.7" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.1" + Task = "(L1) Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.2" + Task = "(L1) Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.3" + Task = "(L1) Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.4" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\privatefw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\privatefw.log"; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.5" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.6" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.7" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.1" + Task = "(L1) Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.2" + Task = "(L1) Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.3" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.4" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.5" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.6" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\publicfw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\publicfw.log"; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.7" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.8" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.9" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "18.1.1.1" + Task = "(L1) Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.1.2" + Task = "(L1) Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.2.2" + Task = "(L1) Ensure 'Allow users to enable online speech recognition services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "AllowInputPersonalization" ` + | Select-Object -ExpandProperty "AllowInputPersonalization" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.3" + Task = "(L2) Ensure 'Allow Online Tips' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "AllowOnlineTips" ` + | Select-Object -ExpandProperty "AllowOnlineTips" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.1" + Task = "(L1) Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.2" + Task = "(L1) Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.3" + Task = "(L1) Ensure 'Configure SMB v1 server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.4" + Task = "(L1) Ensure 'Enable Certificate Padding' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Wintrust\Config" ` + -Name "EnableCertPaddingCheck" ` + | Select-Object -ExpandProperty "EnableCertPaddingCheck" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.5" + Task = "(L1) Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.6" + Task = "(L1) Ensure 'NetBT NodeType configuration' is set to 'Enabled: P-node (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.7" + Task = "(L1) Ensure 'WDigest Authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.1" + Task = "(L1) Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.2" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.3" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.4" + Task = "(L2) Ensure 'MSS: (DisableSavePassword) Prevent the dial-up password from being saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasMan\Parameters" ` + -Name "disablesavepassword" ` + | Select-Object -ExpandProperty "disablesavepassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.5" + Task = "(L1) Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.6" + Task = "(L2) Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "KeepAliveTime" ` + | Select-Object -ExpandProperty "KeepAliveTime" + + if ($regValue -ne 300000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 300000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.7" + Task = "(L1) Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.8" + Task = "(L2) Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "PerformRouterDiscovery" ` + | Select-Object -ExpandProperty "PerformRouterDiscovery" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.9" + Task = "(L1) Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.10" + Task = "(L1) Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires' is set to 'Enabled: 5 or fewer seconds'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScreenSaverGracePeriod" ` + | Select-Object -ExpandProperty "ScreenSaverGracePeriod" + + if ($regValue -notmatch "^[0-5]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[0-5]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.11" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.12" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.13" + Task = "(L1) Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security" ` + -Name "WarningLevel" ` + | Select-Object -ExpandProperty "WarningLevel" + + if (($regValue -gt 90)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 90" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.1" + Task = "(L1) Ensure 'Configure multicast DNS (mDNS) protocol' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMDNS" ` + | Select-Object -ExpandProperty "EnableMDNS" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.2" + Task = "(L1) Ensure 'Configure NetBIOS settings' is set to 2 - 'Enabled: Disable NetBIOS name resolution on public networks' or 0 - 'Enabled: Disable NetBIOS name resolution'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableNetBIOS" ` + | Select-Object -ExpandProperty "EnableNetBIOS" + + if (($regValue -ne 2) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2 or 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.3" + Task = "(L2) Ensure 'Turn off default IPv6 DNS Servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "DisableIPv6DefaultDnsServers" ` + | Select-Object -ExpandProperty "DisableIPv6DefaultDnsServers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.4" + Task = "(L1) Ensure 'Turn off multicast name resolution' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.5.1" + Task = "(L2) Ensure 'Enable Font Providers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableFontProviders" ` + | Select-Object -ExpandProperty "EnableFontProviders" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.1" + Task = "(L1) Ensure 'Audit client does not support encryption' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanServer" ` + -Name "AuditClientDoesNotSupportEncryption" ` + | Select-Object -ExpandProperty "AuditClientDoesNotSupportEncryption" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.2" + Task = "(L1) Ensure 'Audit client does not support signing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanServer" ` + -Name "AuditClientDoesNotSupportSigning" ` + | Select-Object -ExpandProperty "AuditClientDoesNotSupportSigning" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.3" + Task = "(L1) Ensure 'Audit insecure guest logon' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanServer" ` + -Name "AuditInsecureGuestLogon" ` + | Select-Object -ExpandProperty "AuditInsecureGuestLogon" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.4" + Task = "(L1) Ensure 'Enable authentication rate limiter' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanServer" ` + -Name "EnableAuthRateLimiter" ` + | Select-Object -ExpandProperty "EnableAuthRateLimiter" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.5" + Task = "(L1) Ensure 'Enable remote mailslots' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Bowser" ` + -Name "EnableMailslots" ` + | Select-Object -ExpandProperty "EnableMailslots" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.6" + Task = "(L1) Ensure 'Mandate the minimum version of SMB' is set to 'Enabled: 3.1.1'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanServer" ` + -Name "MinSmb2Dialect" ` + | Select-Object -ExpandProperty "MinSmb2Dialect" + + if (($regValue -ne 785)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 785" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.7" + Task = "(L1) Ensure 'Set authentication rate limiter delay (milliseconds)' is set to 'Enabled: 2000' or more" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanServer" ` + -Name "InvalidAuthenticationDelayTimeInMs" ` + | Select-Object -ExpandProperty "InvalidAuthenticationDelayTimeInMs" + + if (($regValue -lt 2000)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 2000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.1" + Task = "(L1) Ensure 'Audit insecure guest logon' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AuditInsecureGuestLogon" ` + | Select-Object -ExpandProperty "AuditInsecureGuestLogon" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.2" + Task = "(L1) Ensure 'Audit server does not support encryption' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AuditServerDoesNotSupportEncryption" ` + | Select-Object -ExpandProperty "AuditServerDoesNotSupportEncryption" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.3" + Task = "(L1) Ensure 'Audit server does not support signing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AuditServerDoesNotSupportSigning" ` + | Select-Object -ExpandProperty "AuditServerDoesNotSupportSigning" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.4" + Task = "(L1) Ensure 'Enable insecure guest logons' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.5" + Task = "(L1) Ensure 'Enable remote mailslots' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider" ` + -Name "EnableMailslots" ` + | Select-Object -ExpandProperty "EnableMailslots" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.6" + Task = "(L1) Ensure 'Mandate the minimum version of SMB' is set to 'Enabled: 3.1.1'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "MinSmb2Dialect" ` + | Select-Object -ExpandProperty "MinSmb2Dialect" + + if (($regValue -ne 785)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 785" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.7" + Task = "(L1) Ensure 'Require Encryption' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "RequireEncryption" ` + | Select-Object -ExpandProperty "RequireEncryption" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 A" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnDomain" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 B" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnPublicNet" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 C" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (EnableLLTDIO)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableLLTDIO" ` + | Select-Object -ExpandProperty "EnableLLTDIO" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 D" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitLLTDIOOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitLLTDIOOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 A" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnDomain" ` + | Select-Object -ExpandProperty "AllowRspndrOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 B" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnPublicNet" ` + | Select-Object -ExpandProperty "AllowRspndrOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 C" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (EnableRspndr)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableRspndr" ` + | Select-Object -ExpandProperty "EnableRspndr" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 D" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitRspndrOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitRspndrOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.10.2" + Task = "(L2) Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.2" + Task = "(L1) Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.3" + Task = "(L1) Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.4" + Task = "(L1) Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_StdDomainUserSetLocation" ` + | Select-Object -ExpandProperty "NC_StdDomainUserSetLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 A" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares' (\\*\NETLOGON)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if ($regValue -eq $null) { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object { $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "RequirePrivacy=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 B" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares' (\\*\SYSVOL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if ($regValue -eq $null) { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object { $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "RequirePrivacy=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.19.2.1" + Task = "(L2) Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "DisabledComponents" ` + | Select-Object -ExpandProperty "DisabledComponents" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 A" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (EnableRegistrars)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "EnableRegistrars" ` + | Select-Object -ExpandProperty "EnableRegistrars" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 B" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableUPnPRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableUPnPRegistrar" ` + | Select-Object -ExpandProperty "DisableUPnPRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 C" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableInBand802DOT11Registrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableInBand802DOT11Registrar" ` + | Select-Object -ExpandProperty "DisableInBand802DOT11Registrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 D" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableFlashConfigRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableFlashConfigRegistrar" ` + | Select-Object -ExpandProperty "DisableFlashConfigRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 E" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableWPDRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableWPDRegistrar" ` + | Select-Object -ExpandProperty "DisableWPDRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.2" + Task = "(L2) Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI" ` + -Name "DisableWcnUi" ` + | Select-Object -ExpandProperty "DisableWcnUi" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.1" + Task = "(L1) Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled: 3 = Prevent Wi-Fi when on Ethernet'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fMinimizeConnections" ` + | Select-Object -ExpandProperty "fMinimizeConnections" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.2" + Task = "(L1) Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.23.2.1" + Task = "(L1) Ensure 'Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config" ` + -Name "AutoConnectAllowedOEM" ` + | Select-Object -ExpandProperty "AutoConnectAllowedOEM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.1" + Task = "(L1) Ensure 'Allow Print Spooler to accept client connections' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "RegisterSpoolerRemoteRpcEndPoint" ` + | Select-Object -ExpandProperty "RegisterSpoolerRemoteRpcEndPoint" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.2" + Task = "(L1) Ensure 'Configure Redirection Guard' is set to 'Enabled: Redirection Guard Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "RedirectionGuardPolicy" ` + | Select-Object -ExpandProperty "RedirectionGuardPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.3" + Task = "(L1) Ensure 'Configure RPC connection settings: Protocol to use for outgoing RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcUseNamedPipeProtocol" ` + | Select-Object -ExpandProperty "RpcUseNamedPipeProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.4" + Task = "(L1) Ensure 'Configure RPC connection settings: Use authentication for outgoing RPC connections' is set to 'Enabled: Default'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcAuthentication" ` + | Select-Object -ExpandProperty "RpcAuthentication" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.5" + Task = "(L1) Ensure 'Configure RPC listener settings: Protocols to allow for incoming RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcProtocols" ` + | Select-Object -ExpandProperty "RpcProtocols" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.6" + Task = "(L1) Ensure 'Configure RPC listener settings: Authentication protocol to use for incoming RPC connections:' is set to 'Enabled: 0 - Negotiate' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "ForceKerberosForRpc" ` + | Select-Object -ExpandProperty "ForceKerberosForRpc" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0 or 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.7" + Task = "(L1) Ensure 'Configure RPC over TCP port' is set to 'Enabled: 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcTcpPort" ` + | Select-Object -ExpandProperty "RpcTcpPort" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.8" + Task = "(L1) Ensure 'Configure RPC packet level privacy setting for incoming connections' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print" ` + -Name "RpcAuthnLevelPrivacyEnabled" ` + | Select-Object -ExpandProperty "RpcAuthnLevelPrivacyEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.9" + Task = "(L2) Ensure 'Configure Windows protected print' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\WPP" ` + -Name "WindowsProtectedPrintGroupPolicyState" ` + | Select-Object -ExpandProperty "WindowsProtectedPrintGroupPolicyState" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.10" + Task = "(L1) Ensure 'Limits print driver installation to Administrators' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "RestrictDriverInstallationToAdministrators" ` + | Select-Object -ExpandProperty "RestrictDriverInstallationToAdministrators" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.11" + Task = "(L1) Ensure 'Manage processing of Queue-specific files' is set to 'Enabled: Limit Queue-specific files to Color profiles'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "CopyFilesPolicy" ` + | Select-Object -ExpandProperty "CopyFilesPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.12" + Task = "(L1) Ensure 'Point and Print Restrictions: When installing drivers for a new connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "NoWarningNoElevationOnInstall" ` + | Select-Object -ExpandProperty "NoWarningNoElevationOnInstall" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.13" + Task = "(L1) Ensure 'Point and Print Restrictions: When updating drivers for an existing connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "UpdatePromptSettings" ` + | Select-Object -ExpandProperty "UpdatePromptSettings" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.1.1" + Task = "(L2) Ensure 'Turn off notifications network usage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.2" + Task = "(L2) Ensure 'Remove Personalized Website Recommendations from the Recommended section in the Start Menu' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "HideRecommendedPersonalizedSites" ` + | Select-Object -ExpandProperty "HideRecommendedPersonalizedSites" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.3.1" + Task = "(L1) Ensure 'Include command line in process creation events' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.1" + Task = "(L1) Ensure 'Encryption Oracle Remediation' is set to 'Enabled: Force Updated Clients'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.2" + Task = "(L1) Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.1" + Task = "(L1) Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.2" + Task = "(L1) Ensure 'Turn On Virtualization Based Security: Select Platform Security Level' is set to 1 - 'Secure Boot' or 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if (($regValue -ne 1) -and ($regValue -ne 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.3" + Task = "(L1) Ensure 'Turn On Virtualization Based Security: Virtualization Based Protection of Code Integrity' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.4" + Task = "(L1) Ensure 'Turn On Virtualization Based Security: Require UEFI Memory Attributes Table' is set to 'True (checked)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HVCIMATRequired" ` + | Select-Object -ExpandProperty "HVCIMATRequired" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.5" + Task = "(L1) Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.6" + Task = "(L1) Ensure 'Turn On Virtualization Based Security: Secure Launch Configuration' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureSystemGuardLaunch" ` + | Select-Object -ExpandProperty "ConfigureSystemGuardLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.7" + Task = "(L1) Ensure 'Turn On Virtualization Based Security: Kernel-mode Hardware-enforced Stack Protection' is set to 'Enabled: Enabled in enforcement mode'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureKernelShadowStacksLaunch" ` + | Select-Object -ExpandProperty "ConfigureKernelShadowStacksLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.1" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClasses" ` + | Select-Object -ExpandProperty "DenyDeviceClasses" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.2 A" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the SBP2 Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "{d48179be-ec20-11d1-b6b8-00c04fa372a7}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {d48179be-ec20-11d1-b6b8-00c04fa372a7}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.2 B" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the IEC-61883 Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "2" ` + | Select-Object -ExpandProperty "2" + + if ($regValue -ne "{7ebefbc0-3200-11d2-b4c2-00a0C9697d07}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {7ebefbc0-3200-11d2-b4c2-00a0C9697d07}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.2 C" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the AVC Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "3" ` + | Select-Object -ExpandProperty "3" + + if ($regValue -ne "{c06ff265-ae09-48f0-812c-16753d7cba83}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {c06ff265-ae09-48f0-812c-16753d7cba83}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.2 D" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 Host Bus Controller Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "4" ` + | Select-Object -ExpandProperty "4" + + if ($regValue -ne "{6bdd1fc1-810f-11d0-bec7-08002be2092f}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {6bdd1fc1-810f-11d0-bec7-08002be2092f}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.3" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Also apply to matching devices that are already installed.' is set to 'True' (checked)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClassesRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceClassesRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.2" + Task = "(L1) Ensure 'Prevent device metadata retrieval from the Internet' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" ` + -Name "PreventDeviceMetadataFromNetwork" ` + | Select-Object -ExpandProperty "PreventDeviceMetadataFromNetwork" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.13.1" + Task = "(L1) Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.2" + Task = "(L1) Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.3" + Task = "(L1) Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.4" + Task = "(L1) Ensure 'Configure security policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.5" + Task = "(L1) Ensure 'Configure security policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.6" + Task = "(L1) Ensure 'Continue experiences on this device' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableCdp" ` + | Select-Object -ExpandProperty "EnableCdp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.7" + Task = "(L1) Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableBkGndGroupPolicy" ` + | Select-Object -ExpandProperty "DisableBkGndGroupPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.1" + Task = "(L2) Ensure 'Turn off access to the Store' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoUseStoreOpenWith" ` + | Select-Object -ExpandProperty "NoUseStoreOpenWith" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.2" + Task = "(L1) Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.3" + Task = "(L2) Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC" ` + -Name "PreventHandwritingDataSharing" ` + | Select-Object -ExpandProperty "PreventHandwritingDataSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.4" + Task = "(L2) Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports" ` + -Name "PreventHandwritingErrorReports" ` + | Select-Object -ExpandProperty "PreventHandwritingErrorReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.5" + Task = "(L2) Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard" ` + -Name "ExitOnMSICW" ` + | Select-Object -ExpandProperty "ExitOnMSICW" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.6" + Task = "(L1) Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.7" + Task = "(L2) Ensure 'Turn off printing over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.8" + Task = "(L2) Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Registration Wizard Control" ` + -Name "NoRegistration" ` + | Select-Object -ExpandProperty "NoRegistration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.9" + Task = "(L2) Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion" ` + -Name "DisableContentFileUpdates" ` + | Select-Object -ExpandProperty "DisableContentFileUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.10" + Task = "(L2) Ensure 'Turn off the `"Order Prints`" picture task' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoOnlinePrintsWizard" ` + | Select-Object -ExpandProperty "NoOnlinePrintsWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.11" + Task = "(L2) Ensure 'Turn off the `"Publish to Web`" task for files and folders' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoPublishingWizard" ` + | Select-Object -ExpandProperty "NoPublishingWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.12" + Task = "(L2) Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client" ` + -Name "CEIP" ` + | Select-Object -ExpandProperty "CEIP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13" + Task = "(L2) Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows" ` + -Name "CEIPEnable" ` + | Select-Object -ExpandProperty "CEIPEnable" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.14 A" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (Disabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.14 B" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (DoReport)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting" ` + -Name "DoReport" ` + | Select-Object -ExpandProperty "DoReport" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 A" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitBehavior)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitBehavior" ` + | Select-Object -ExpandProperty "DevicePKInitBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 B" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitEnabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitEnabled" ` + | Select-Object -ExpandProperty "DevicePKInitEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.1" + Task = "(BL) Ensure 'Enumeration policy for external devices incompatible with Kernel DMA Protection' is set to 'Enabled: Block All'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.1" + Task = "(L1) Ensure 'Configure password backup directory' is set to 2 - 'Enabled: Active Directory' or 1 - 'Enabled: Azure Active Directory'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "BackupDirectory" ` + | Select-Object -ExpandProperty "BackupDirectory" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.2" + Task = "(L1) Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PwdExpirationProtectionEnabled" ` + | Select-Object -ExpandProperty "PwdExpirationProtectionEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.3" + Task = "(L1) Ensure 'Enable password encryption' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "ADPasswordEncryptionEnabled" ` + | Select-Object -ExpandProperty "ADPasswordEncryptionEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.4" + Task = "(L1) Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordComplexity" ` + | Select-Object -ExpandProperty "PasswordComplexity" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.5" + Task = "(L1) Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordLength" ` + | Select-Object -ExpandProperty "PasswordLength" + + if (($regValue -lt 15)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.6" + Task = "(L1) Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordAgeDays" ` + | Select-Object -ExpandProperty "PasswordAgeDays" + + if (($regValue -gt 30 -or $regValue -lt 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30 and x >= 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.7" + Task = "(L1) Ensure 'Post-authentication actions: Grace period (hours)' is set to 'Enabled: 8 or fewer hours, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PostAuthenticationResetDelay" ` + | Select-Object -ExpandProperty "PostAuthenticationResetDelay" + + if (($regValue -gt 8 -or $regValue -le 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 8 and x > 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.8" + Task = "(L1) Ensure 'Post-authentication actions: Actions' is set to 3 - 'Enabled: Reset the password and logoff the managed account' or 5 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PostAuthenticationActions" ` + | Select-Object -ExpandProperty "PostAuthenticationActions" + + if (($regValue -ne 3) -and ($regValue -ne 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3 or 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.1" + Task = "(L1) Ensure 'Allow Custom SSPs and APs to be loaded into LSASS' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowCustomSSPsAPs" ` + | Select-Object -ExpandProperty "AllowCustomSSPsAPs" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.2" + Task = "(L1) Ensure 'Configures LSASS to run as a protected process' is set to 'Enabled: Enabled with UEFI Lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RunAsPPL" ` + | Select-Object -ExpandProperty "RunAsPPL" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.1" + Task = "(L2) Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International" ` + -Name "BlockUserInputMethodsForSignIn" ` + | Select-Object -ExpandProperty "BlockUserInputMethodsForSignIn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.1" + Task = "(L1) Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockUserFromShowingAccountDetailsOnSignin" ` + | Select-Object -ExpandProperty "BlockUserFromShowingAccountDetailsOnSignin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.2" + Task = "(L1) Ensure 'Do not display network selection UI' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.3" + Task = "(L1) Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DontEnumerateConnectedUsers" ` + | Select-Object -ExpandProperty "DontEnumerateConnectedUsers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.4" + Task = "(L1) Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.5" + Task = "(L1) Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.6" + Task = "(L1) Ensure 'Turn off picture password sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockDomainPicturePassword" ` + | Select-Object -ExpandProperty "BlockDomainPicturePassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.7" + Task = "(L1) Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.30.1.1" + Task = "(L1) Ensure 'Block NetBIOS-based discovery for domain controller location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Netlogon\Parameters" ` + -Name "BlockNetbiosDiscovery" ` + | Select-Object -ExpandProperty "BlockNetbiosDiscovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.31.1" + Task = "(L2) Ensure 'Allow Clipboard synchronization across devices' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowCrossDeviceClipboard" ` + | Select-Object -ExpandProperty "AllowCrossDeviceClipboard" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.31.2" + Task = "(L2) Ensure 'Allow upload of User Activities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "UploadUserActivities" ` + | Select-Object -ExpandProperty "UploadUserActivities" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.1" + Task = "(L1) Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.2" + Task = "(L1) Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.3" + Task = "(BL) Ensure 'Allow standby states (S1-S3) when sleeping (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.4" + Task = "(BL) Ensure 'Allow standby states (S1-S3) when sleeping (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.5" + Task = "(L1) Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.6" + Task = "(L1) Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.1" + Task = "(L1) Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.2" + Task = "(L1) Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.36.1" + Task = "(L1) Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" ` + -Name "EnableAuthEpResolution" ` + | Select-Object -ExpandProperty "EnableAuthEpResolution" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.36.2" + Task = "(L1) Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.39.1" + Task = "(L1) Ensure 'Configure SAM change password RPC methods policy' is set to 'Enabled: Block all change password RPC methods'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\SAM" ` + -Name "SamrChangeUserPasswordApiPolicy" ` + | Select-Object -ExpandProperty "SamrChangeUserPasswordApiPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1" + Task = "(L2) Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.11.1" + Task = "(L2) Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d}" ` + -Name "ScenarioExecutionEnabled" ` + | Select-Object -ExpandProperty "ScenarioExecutionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.49.1" + Task = "(L2) Ensure 'Turn off the advertising ID' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" ` + -Name "DisabledByGroupPolicy" ` + | Select-Object -ExpandProperty "DisabledByGroupPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.51.1.1" + Task = "(L1) Ensure 'Enable Windows NTP Client' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.51.1.2" + Task = "(L1) Ensure 'Enable Windows NTP Server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.52" + Task = "(L1) Ensure 'Configure the behavior of the sudo command' is set to 'Enabled: Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Sudo" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.3.1" + Task = "(L2) Ensure 'Turn off API Sampling' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppCompat" ` + -Name "DisableAPISamping" ` + | Select-Object -ExpandProperty "DisableAPISamping" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.3.2" + Task = "(L2) Ensure 'Turn off Application Footprint' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppCompat" ` + -Name "DisableApplicationFootprint" ` + | Select-Object -ExpandProperty "DisableApplicationFootprint" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.3.3" + Task = "(L2) Ensure 'Turn off Install Tracing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppCompat" ` + -Name "DisableInstallTracing" ` + | Select-Object -ExpandProperty "DisableInstallTracing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.4.1" + Task = "(L2) Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager" ` + -Name "AllowSharedLocalAppData" ` + | Select-Object -ExpandProperty "AllowSharedLocalAppData" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.4.2" + Task = "(L1) Ensure 'Not allow per-user unsigned packages to install by default (requires explicitly allow per install)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Appx" ` + -Name "DisablePerUserUnsignedPackagesByDefault" ` + | Select-Object -ExpandProperty "DisablePerUserUnsignedPackagesByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.4.3" + Task = "(L1) Ensure 'Prevent non-admin users from installing packaged Windows apps' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Appx" ` + -Name "BlockNonAdminUserInstall" ` + | Select-Object -ExpandProperty "BlockNonAdminUserInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.5.1" + Task = "(L1) Ensure 'Let Windows apps activate with voice while the system is locked' is set to 'Enabled: Force Deny'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsActivateWithVoiceAboveLock" ` + | Select-Object -ExpandProperty "LetAppsActivateWithVoiceAboveLock" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.6.1" + Task = "(L1) Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.6.2" + Task = "(L2) Ensure 'Block launching Universal Windows apps with Windows Runtime API access from hosted content.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "BlockHostedAppAccessWinRT" ` + | Select-Object -ExpandProperty "BlockHostedAppAccessWinRT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.8.1" + Task = "(L1) Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.8.2" + Task = "(L1) Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.8.3" + Task = "(L1) Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.1" + Task = "(L1) Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.1" + Task = "(BL) Ensure 'Allow access to BitLocker-protected fixed data drives from earlier versions of Windows' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVDiscoveryVolumeType" ` + | Select-Object -ExpandProperty "FDVDiscoveryVolumeType" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: This value should be empty." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.2" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecovery" ` + | Select-Object -ExpandProperty "FDVRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Allow data recovery agent' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVManageDRA" ` + | Select-Object -ExpandProperty "FDVManageDRA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Recovery Password' is set to 2 - 'Enabled: Allow 48-digit recovery password' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecoveryPassword" ` + | Select-Object -ExpandProperty "FDVRecoveryPassword" + + if (($regValue -ne 2) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2 or 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Recovery Key' is set to 2 - 'Enabled: Allow 256-bit recovery key' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecoveryKey" ` + | Select-Object -ExpandProperty "FDVRecoveryKey" + + if (($regValue -ne 2) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2 or 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVHideRecoveryPage" ` + | Select-Object -ExpandProperty "FDVHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Save BitLocker recovery information to AD DS for fixed data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "FDVActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Configure storage of BitLocker recovery information to AD DS' is set to 'Enabled: Backup recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "FDVActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for fixed data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "FDVRequireActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.10" + Task = "(BL) Ensure 'Configure use of hardware-based encryption for fixed data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVHardwareEncryption" ` + | Select-Object -ExpandProperty "FDVHardwareEncryption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.11" + Task = "(BL) Ensure 'Configure use of passwords for fixed data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVPassphrase" ` + | Select-Object -ExpandProperty "FDVPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.12" + Task = "(BL) Ensure 'Configure use of smart cards on fixed data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVAllowUserCert" ` + | Select-Object -ExpandProperty "FDVAllowUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1.13" + Task = "(BL) Ensure 'Configure use of smart cards on fixed data drives: Require use of smart cards on fixed data drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVEnforceUserCert" ` + | Select-Object -ExpandProperty "FDVEnforceUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.1" + Task = "(BL) Ensure 'Allow enhanced PINs for startup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseEnhancedPin" ` + | Select-Object -ExpandProperty "UseEnhancedPin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.2" + Task = "(BL) Ensure 'Allow Secure Boot for integrity validation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSAllowSecureBootForIntegrity" ` + | Select-Object -ExpandProperty "OSAllowSecureBootForIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecovery" ` + | Select-Object -ExpandProperty "OSRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Allow data recovery agent' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSManageDRA" ` + | Select-Object -ExpandProperty "OSManageDRA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Recovery Password' is set to 'Enabled: Require 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecoveryPassword" ` + | Select-Object -ExpandProperty "OSRecoveryPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Recovery Key' is set to 'Enabled: Do not allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecoveryKey" ` + | Select-Object -ExpandProperty "OSRecoveryKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSHideRecoveryPage" ` + | Select-Object -ExpandProperty "OSHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Save BitLocker recovery information to AD DS for operating system drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "OSActiveDirectoryBackup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Configure storage of BitLocker recovery information to AD DS:' is set to 'Enabled: Store recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "OSActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.10" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for operating system drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "OSRequireActiveDirectoryBackup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.11" + Task = "(BL) Ensure 'Configure use of hardware-based encryption for operating system drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSHardwareEncryption" ` + | Select-Object -ExpandProperty "OSHardwareEncryption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.12" + Task = "(BL) Ensure 'Configure use of passwords for operating system drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSPassphrase" ` + | Select-Object -ExpandProperty "OSPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.13" + Task = "(BL) Ensure 'Require additional authentication at startup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseAdvancedStartup" ` + | Select-Object -ExpandProperty "UseAdvancedStartup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.2.14" + Task = "(BL) Ensure 'Require additional authentication at startup: Allow BitLocker without a compatible TPM' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "EnableBDEWithNoTPM" ` + | Select-Object -ExpandProperty "EnableBDEWithNoTPM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.1" + Task = "(BL) Ensure 'Allow access to BitLocker-protected removable data drives from earlier versions of Windows' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVDiscoveryVolumeType" ` + | Select-Object -ExpandProperty "RDVDiscoveryVolumeType" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: This value should be empty." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.2" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecovery" ` + | Select-Object -ExpandProperty "RDVRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Allow data recovery agent' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVManageDRA" ` + | Select-Object -ExpandProperty "RDVManageDRA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Recovery Password' is set to 'Enabled: Do not allow 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecoveryPassword" ` + | Select-Object -ExpandProperty "RDVRecoveryPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Recovery Key' is set to 'Enabled: Do not allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecoveryKey" ` + | Select-Object -ExpandProperty "RDVRecoveryKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVHideRecoveryPage" ` + | Select-Object -ExpandProperty "RDVHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Save BitLocker recovery information to AD DS for removable data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "RDVActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Configure storage of BitLocker recovery information to AD DS:' is set to 'Enabled: Backup recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "RDVActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for removable data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "RDVRequireActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.10" + Task = "(BL) Ensure 'Configure use of hardware-based encryption for removable data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVHardwareEncryption" ` + | Select-Object -ExpandProperty "RDVHardwareEncryption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.11" + Task = "(BL) Ensure 'Configure use of passwords for removable data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVPassphrase" ` + | Select-Object -ExpandProperty "RDVPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.12" + Task = "(BL) Ensure 'Configure use of smart cards on removable data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVAllowUserCert" ` + | Select-Object -ExpandProperty "RDVAllowUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.13" + Task = "(BL) Ensure 'Configure use of smart cards on removable data drives: Require use of smart cards on removable data drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVEnforceUserCert" ` + | Select-Object -ExpandProperty "RDVEnforceUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.14" + Task = "(BL) Ensure 'Deny write access to removable drives not protected by BitLocker' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\Microsoft\FVE" ` + -Name "RDVDenyWriteAccess" ` + | Select-Object -ExpandProperty "RDVDenyWriteAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.3.15" + Task = "(BL) Ensure 'Deny write access to removable drives not protected by BitLocker: Do not allow write access to devices configured in another organization' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVDenyCrossOrg" ` + | Select-Object -ExpandProperty "RDVDenyCrossOrg" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.4" + Task = "(BL) Ensure 'Disable new DMA devices when this computer is locked' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "DisableExternalDMAUnderLock" ` + | Select-Object -ExpandProperty "DisableExternalDMAUnderLock" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.11.1" + Task = "(L2) Ensure 'Allow Use of Camera' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera" ` + -Name "AllowCamera" ` + | Select-Object -ExpandProperty "AllowCamera" + + if ($regValue -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam" ` + -Name "Value" ` + | Select-Object -ExpandProperty "Value" + + if ($regValue -match "Deny") { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Camera is not deactivated." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "18.10.13.1" + Task = "(L1) Ensure 'Turn off cloud consumer account state content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableConsumerAccountStateContent" ` + | Select-Object -ExpandProperty "DisableConsumerAccountStateContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.13.2" + Task = "(L2) Ensure 'Turn off cloud optimized content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableCloudOptimizedContent" ` + | Select-Object -ExpandProperty "DisableCloudOptimizedContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.13.3" + Task = "(L1) Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.1" + Task = "(L1) Ensure 'Require pin for pairing' is set to 'Enabled: First Time' OR 'Enabled: Always'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect" ` + -Name "RequirePinForPairing" ` + | Select-Object -ExpandProperty "RequirePinForPairing" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.1" + Task = "(L1) Ensure 'Do not display the password reveal button' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.2" + Task = "(L1) Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.3" + Task = "(L1) Ensure 'Prevent the use of security questions for local accounts' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "NoLocalPasswordResetQuestions" ` + | Select-Object -ExpandProperty "NoLocalPasswordResetQuestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.1" + Task = "(L1) Ensure 'Allow Diagnostic Data' is set to '0 - Enabled: Diagnostic data off (not recommended)' or '1 - Enabled: Send required diagnostic data'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0 or 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.2" + Task = "(L2) Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableEnterpriseAuthProxy" ` + | Select-Object -ExpandProperty "DisableEnterpriseAuthProxy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.3" + Task = "(L1) Ensure 'Disable OneSettings Downloads' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableOneSettingsDownloads" ` + | Select-Object -ExpandProperty "DisableOneSettingsDownloads" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.4" + Task = "(L1) Ensure 'Do not show feedback notifications' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DoNotShowFeedbackNotifications" ` + | Select-Object -ExpandProperty "DoNotShowFeedbackNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.5" + Task = "(L1) Ensure 'Enable OneSettings Auditing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "EnableOneSettingsAuditing" ` + | Select-Object -ExpandProperty "EnableOneSettingsAuditing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.6" + Task = "(L1) Ensure 'Limit Diagnostic Log Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDiagnosticLogCollection" ` + | Select-Object -ExpandProperty "LimitDiagnosticLogCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.7" + Task = "(L1) Ensure 'Limit Dump Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDumpCollection" ` + | Select-Object -ExpandProperty "LimitDumpCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.1" + Task = "(L1) Ensure 'Download Mode' is NOT set to 3 - 'Enabled: Internet'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization" ` + -Name "DODownloadMode" ` + | Select-Object -ExpandProperty "DODownloadMode" + + if ($regValue -notmatch "^(0|1|2|99|100)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(0|1|2|99|100)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.1" + Task = "(L2) Ensure 'Enable App Installer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableAppInstaller" ` + | Select-Object -ExpandProperty "EnableAppInstaller" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.2" + Task = "(L1) Ensure 'Enable App Installer Experimental Features' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableExperimentalFeatures" ` + | Select-Object -ExpandProperty "EnableExperimentalFeatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.3" + Task = "(L1) Ensure 'Enable App Installer Hash Override' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableHashOverride" ` + | Select-Object -ExpandProperty "EnableHashOverride" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.4" + Task = "(L1) Ensure 'Enable App Installer Local Archive Malware Scan Override' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableLocalArchiveMalwareScanOverride" ` + | Select-Object -ExpandProperty "EnableLocalArchiveMalwareScanOverride" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.5" + Task = "(L1) Ensure 'Enable App Installer Microsoft Store Source Certificate Validation Bypass' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableBypassCertificatePinningForMicrosoftStore" ` + | Select-Object -ExpandProperty "EnableBypassCertificatePinningForMicrosoftStore" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.6" + Task = "(L1) Ensure 'Enable App Installer ms-appinstaller protocol' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableMSAppInstallerProtocol" ` + | Select-Object -ExpandProperty "EnableMSAppInstallerProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.7" + Task = "(L2) Ensure 'Enable Windows Package Manager command line interfaces' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableWindowsPackageManagerCommandLineInterfaces" ` + | Select-Object -ExpandProperty "EnableWindowsPackageManagerCommandLineInterfaces" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.1.1" + Task = "(L1) Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.1.2" + Task = "(L1) Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.2.1" + Task = "(L1) Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.2.2" + Task = "(L1) Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 196608)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.3.1" + Task = "(L1) Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.3.2" + Task = "(L1) Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.4.1" + Task = "(L1) Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.4.2" + Task = "(L1) Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.2" + Task = "(L2) Ensure 'Turn off account-based insights, recent, favorite, and recommended files in File Explorer' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "DisableGraphRecentItems" ` + | Select-Object -ExpandProperty "DisableGraphRecentItems" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.3" + Task = "(L1) Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.4" + Task = "(L1) Ensure 'Do not apply the Mark of the Web tag to files copied from insecure sources' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "DisableMotWOnInsecurePathCopy" ` + | Select-Object -ExpandProperty "DisableMotWOnInsecurePathCopy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.5" + Task = "(L1) Ensure 'Turn off heap termination on corruption' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.6" + Task = "(L1) Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.37.1" + Task = "(L2) Ensure 'Turn off location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.41.1" + Task = "(L2) Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging" ` + -Name "AllowMessageSync" ` + | Select-Object -ExpandProperty "AllowMessageSync" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.1" + Task = "(L1) Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount" ` + -Name "DisableUserAuth" ` + | Select-Object -ExpandProperty "DisableUserAuth" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.4.1" + Task = "(L1) Ensure 'Enable EDR in block mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Features" ` + -Name "PassiveRemediation" ` + | Select-Object -ExpandProperty "PassiveRemediation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.5.1" + Task = "(L1) Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.5.2" + Task = "(L2) Ensure 'Join Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.1" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 A" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office communication application from creating child processes'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" ` + -Name "26190899-1602-49e8-8b27-eb1d0a1ce869" ` + | Select-Object -ExpandProperty "26190899-1602-49e8-8b27-eb1d0a1ce869" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 B" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating executable content'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 C" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block abuse of exploited vulnerable signed drivers'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 D" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block execution of potentially obfuscated scripts'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 E" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from injecting code into other processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 F" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Adobe Reader from creating child processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 G" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Win32 API calls from Office macro'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 H" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block credential stealing from the Windows local security authority subsystem (lsass.exe)'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 I" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block untrusted and unsigned processes that run from USB'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 J" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block executable content from email client and webmail'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 K" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block JavaScript or VBScript from launching downloaded executable content'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 L" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating child processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 M" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block persistence through WMI event subscription'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.3.1" + Task = "(L1) Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.7.1" + Task = "(L1) Ensure 'Enable file hash computation feature' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine" ` + -Name "EnableFileHashComputation" ` + | Select-Object -ExpandProperty "EnableFileHashComputation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.8.1" + Task = "(L2) Ensure 'Convert warn verdict to block' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\NIS" ` + -Name "EnableConvertWarnToBlock" ` + | Select-Object -ExpandProperty "EnableConvertWarnToBlock" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.1" + Task = "(L1) Ensure 'Configure real-time protection and Security Intelligence Updates during OOBE' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "OobeEnableRtpAndSigUpdate" ` + | Select-Object -ExpandProperty "OobeEnableRtpAndSigUpdate" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.2" + Task = "(L1) Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.3" + Task = "(L1) Ensure 'Turn off real-time protection' is set to 'Disabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.4" + Task = "(L1) Ensure 'Turn on behavior monitoring' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.5" + Task = "(L1) Ensure 'Turn on script scanning' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableScriptScanning" ` + | Select-Object -ExpandProperty "DisableScriptScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.11.1.1.1" + Task = "(L2) Ensure 'Configure Brute-Force Protection aggressiveness' is set to 1 - 'Enabled: Medium' or 2 - higher" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection" ` + -Name "BruteForceProtectionAggressiveness" ` + | Select-Object -ExpandProperty "BruteForceProtectionAggressiveness" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.11.1.1.2" + Task = "(L1) Ensure 'Configure Remote Encryption Protection Mode' is set to 2 - 'Enabled: Audit' or 1 - higher" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection" ` + -Name "BruteForceProtectionConfiguredState" ` + | Select-Object -ExpandProperty "BruteForceProtectionConfiguredState" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.11.1.2.1" + Task = "(L2) Ensure 'Configure how aggressively Remote Encryption Protection blocks threats' is set to 1 - 'Enabled: Medium' or 2 - higher" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Remote Encryption Protection" ` + -Name "RemoteEncryptionProtectionAggressiveness" ` + | Select-Object -ExpandProperty "RemoteEncryptionProtectionAggressiveness" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.12.1" + Task = "(L2) Ensure 'Configure Watson events' is set to 'Disabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" ` + -Name "DisableGenericReports" ` + | Select-Object -ExpandProperty "DisableGenericReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.1" + Task = "(L1) Ensure 'Scan excluded files and directories during quick scans' is set to 'Enabled: 1'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "QuickScanIncludeExclusions" ` + | Select-Object -ExpandProperty "QuickScanIncludeExclusions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.2" + Task = "(L1) Ensure 'Scan packed executables' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisablePackedExeScanning" ` + | Select-Object -ExpandProperty "DisablePackedExeScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.3" + Task = "(L1) Ensure 'Scan removable drives' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.4" + Task = "(L1) Ensure 'Trigger a quick scan after X days without any scans' is set to 'Enabled: 7'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DaysUntilAggressiveCatchupQuickScan" ` + | Select-Object -ExpandProperty "DaysUntilAggressiveCatchupQuickScan" + + if (($regValue -ne 7)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 7" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.5" + Task = "(L1) Ensure 'Turn on e-mail scanning' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.16" + Task = "(L1) Ensure 'Configure detection for potentially unwanted applications' is set to 'Enabled: Block'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.17" + Task = "(L1) Ensure 'Control whether exclusions are visible to local users' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "HideExclusionsFromLocalUsers" ` + | Select-Object -ExpandProperty "HideExclusionsFromLocalUsers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.1" + Task = "(L1) Ensure 'Allow auditing events in Microsoft Defender Application Guard' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AuditApplicationGuard" ` + | Select-Object -ExpandProperty "AuditApplicationGuard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.2" + Task = "(L1) Ensure 'Allow camera and microphone access in Microsoft Defender Application Guard' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowCameraMicrophoneRedirection" ` + | Select-Object -ExpandProperty "AllowCameraMicrophoneRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.3" + Task = "(L1) Ensure 'Allow data persistence for Microsoft Defender Application Guard' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowPersistence" ` + | Select-Object -ExpandProperty "AllowPersistence" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.4" + Task = "(L1) Ensure 'Allow files to download and save to the host operating system from Microsoft Defender Application Guard' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "SaveFilesToHost" ` + | Select-Object -ExpandProperty "SaveFilesToHost" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.5" + Task = "(L1) Ensure 'Configure Microsoft Defender Application Guard clipboard settings: Clipboard behavior setting' is set to 'Enabled: Enable clipboard operation from an isolated session to the host'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AppHVSIClipboardSettings" ` + | Select-Object -ExpandProperty "AppHVSIClipboardSettings" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1. " + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found. " + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found. " + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.6" + Task = "(L1) Ensure 'Turn on Microsoft Defender Application Guard in Managed Mode' is set to 'Enabled: 1'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowAppHVSI_ProviderSet" ` + | Select-Object -ExpandProperty "AllowAppHVSI_ProviderSet" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 " + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found. " + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found. " + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.50.1" + Task = "(L2) Ensure 'Enable news and interests on the taskbar' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Feeds" ` + -Name "EnableFeeds" ` + | Select-Object -ExpandProperty "EnableFeeds" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.51.1" + Task = "(L1) Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.1" + Task = "(L2) Ensure 'Turn off Push To Install service' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall" ` + -Name "DisablePushToInstall" ` + | Select-Object -ExpandProperty "DisablePushToInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.2.2" + Task = "(L2) Ensure 'Disable Cloud Clipboard integration for server-to-client data transfer' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\Client" ` + -Name "DisableCloudClipboardIntegration" ` + | Select-Object -ExpandProperty "DisableCloudClipboardIntegration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.2.3" + Task = "(L1) Ensure 'Do not allow passwords to be saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.2.1" + Task = "(L2) Ensure 'Allow users to connect remotely by using Remote Desktop Services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDenyTSConnections" ` + | Select-Object -ExpandProperty "fDenyTSConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.1" + Task = "(L2) Ensure 'Allow UI Automation redirection' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "EnableUiaRedirection" ` + | Select-Object -ExpandProperty "EnableUiaRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.2" + Task = "(L2) Ensure 'Do not allow COM port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCcm" ` + | Select-Object -ExpandProperty "fDisableCcm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.3" + Task = "(L1) Ensure 'Do not allow drive redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.4" + Task = "(L2) Ensure 'Do not allow location redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLocationRedir" ` + | Select-Object -ExpandProperty "fDisableLocationRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.5" + Task = "(L2) Ensure 'Do not allow LPT port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLPT" ` + | Select-Object -ExpandProperty "fDisableLPT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.6" + Task = "(L2) Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisablePNPRedir" ` + | Select-Object -ExpandProperty "fDisablePNPRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.7" + Task = "(L2) Ensure 'Do not allow WebAuthn redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableWebAuthn" ` + | Select-Object -ExpandProperty "fDisableWebAuthn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.8" + Task = "(L2) Ensure 'Restrict clipboard transfer from server to client' is set to 'Enabled: Disable clipboard transfers from server to client'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SCClipLevel" ` + | Select-Object -ExpandProperty "SCClipLevel" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.1" + Task = "(L1) Ensure 'Always prompt for password upon connection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.2" + Task = "(L1) Ensure 'Require secure RPC communication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.3" + Task = "(L1) Ensure 'Require use of specific security layer for remote (RDP) connections' is set to 'Enabled: SSL'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SecurityLayer" ` + | Select-Object -ExpandProperty "SecurityLayer" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.4" + Task = "(L1) Ensure 'Require user authentication for remote connections by using Network Level Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "UserAuthentication" ` + | Select-Object -ExpandProperty "UserAuthentication" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.5" + Task = "(L1) Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.10.1" + Task = "(L2) Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less, but not Never (0)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxIdleTime" ` + | Select-Object -ExpandProperty "MaxIdleTime" + + if (($regValue -gt 900000 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900000 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.10.2" + Task = "(L2) Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxDisconnectionTime" ` + | Select-Object -ExpandProperty "MaxDisconnectionTime" + + if ($regValue -ne 60000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 60000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.11.1" + Task = "(L1) Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.1" + Task = "(L1) Ensure 'Prevent downloading of enclosures' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.2" + Task = "(L1) Ensure 'Turn on Basic feed authentication over HTTP' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "AllowBasicAuthInClear" ` + | Select-Object -ExpandProperty "AllowBasicAuthInClear" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.2" + Task = "(L2) Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCloudSearch" ` + | Select-Object -ExpandProperty "AllowCloudSearch" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.3" + Task = "(L1) Ensure 'Allow Cortana' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCortana" ` + | Select-Object -ExpandProperty "AllowCortana" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.4" + Task = "(L1) Ensure 'Allow Cortana above lock screen' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCortanaAboveLock" ` + | Select-Object -ExpandProperty "AllowCortanaAboveLock" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.5" + Task = "(L1) Ensure 'Allow indexing of encrypted files' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.6" + Task = "(L1) Ensure 'Allow search and Cortana to use location' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowSearchToUseLocation" ` + | Select-Object -ExpandProperty "AllowSearchToUseLocation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.7" + Task = "(L2) Ensure 'Allow search highlights' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "EnableDynamicContentInWSB" ` + | Select-Object -ExpandProperty "EnableDynamicContentInWSB" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.63.1" + Task = "(L2) Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" ` + -Name "NoGenTicket" ` + | Select-Object -ExpandProperty "NoGenTicket" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.1" + Task = "(L2) Ensure 'Disable all apps from Microsoft Store' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "DisableStoreApps" ` + | Select-Object -ExpandProperty "DisableStoreApps" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.2" + Task = "(L1) Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "AutoDownload" ` + | Select-Object -ExpandProperty "AutoDownload" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.3" + Task = "(L1) Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "DisableOSUpgrade" ` + | Select-Object -ExpandProperty "DisableOSUpgrade" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.4" + Task = "(L2) Ensure 'Turn off the Store application' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "RemoveWindowsStore" ` + | Select-Object -ExpandProperty "RemoveWindowsStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.72.1" + Task = "(L1) Ensure 'Allow widgets' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Dsh" ` + -Name "AllowNewsAndInterests" ` + | Select-Object -ExpandProperty "AllowNewsAndInterests" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.1.1" + Task = "(L1) Ensure 'Automatic Data Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "CaptureThreatWindow" ` + | Select-Object -ExpandProperty "CaptureThreatWindow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.1.2" + Task = "(L1) Ensure 'Notify Malicious' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "NotifyMalicious" ` + | Select-Object -ExpandProperty "NotifyMalicious" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.1.3" + Task = "(L1) Ensure 'Notify Password Reuse' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "NotifyPasswordReuse" ` + | Select-Object -ExpandProperty "NotifyPasswordReuse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.1.4" + Task = "(L1) Ensure 'Notify Unsafe App' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "NotifyUnsafeApp" ` + | Select-Object -ExpandProperty "NotifyUnsafeApp" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.1.5" + Task = "(L1) Ensure 'Service Enabled' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "ServiceEnabled" ` + | Select-Object -ExpandProperty "ServiceEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.2.1 A" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (EnableSmartScreen)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.2.1 B" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (ShellSmartScreenLevel)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.78.1" + Task = "(L1) Ensure 'Enables or disables Windows Game Recording and Broadcasting' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR" ` + -Name "AllowGameDVR" ` + | Select-Object -ExpandProperty "AllowGameDVR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.79.1" + Task = "(L1) Ensure 'Enable ESS with Supported Peripherals' is set to 'Enabled: 1'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Policies\PassportForWork\Biometrics" ` + -Name "EnableESSwithSupportedPeripherals" ` + | Select-Object -ExpandProperty "EnableESSwithSupportedPeripherals" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.1" + Task = "(L2) Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowSuggestedAppsInWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowSuggestedAppsInWindowsInkWorkspace" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.2" + Task = "(L1) Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Enabled: Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if (($regValue -ne 1) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.1" + Task = "(L1) Ensure 'Allow user control over installs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.2" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.3" + Task = "(L2) Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.82.1" + Task = "(L1) Ensure 'Configure the transmission of the user's password in the content of MPR notifications sent by winlogon.' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableMPR" ` + | Select-Object -ExpandProperty "EnableMPR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.82.2" + Task = "(L1) Ensure 'Sign-in and lock last interactive user automatically after a restart' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.87.1" + Task = "(L2) Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.87.2" + Task = "(L2) Ensure 'Turn on PowerShell Transcription' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" ` + -Name "EnableTranscripting" ` + | Select-Object -ExpandProperty "EnableTranscripting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.2" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.3" + Task = "(L1) Ensure 'Disallow Digest authentication' is set to 'Enabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.2" + Task = "(L2) Ensure 'Allow remote server management through WinRM' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowAutoConfig" ` + | Select-Object -ExpandProperty "AllowAutoConfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.3" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.4" + Task = "(L1) Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.90.1" + Task = "(L2) Ensure 'Allow Remote Shell Access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS" ` + -Name "AllowRemoteShellAccess" ` + | Select-Object -ExpandProperty "AllowRemoteShellAccess" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.91.1" + Task = "(L1) Ensure 'Allow clipboard sharing with Windows Sandbox' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Sandbox" ` + -Name "AllowClipboardRedirection" ` + | Select-Object -ExpandProperty "AllowClipboardRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.91.2" + Task = "(L2) Ensure 'Allow mapping folders into Windows Sandbox' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Sandbox" ` + -Name "AllowWriteToMappedFolders" ` + | Select-Object -ExpandProperty "AllowWriteToMappedFolders" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.91.3" + Task = "(L1) Ensure 'Allow networking in Windows Sandbox' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Sandbox" ` + -Name "AllowNetworking" ` + | Select-Object -ExpandProperty "AllowNetworking" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.1" + Task = "(L1) Ensure 'Prevent users from modifying settings' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection" ` + -Name "DisallowExploitProtectionOverride" ` + | Select-Object -ExpandProperty "DisallowExploitProtectionOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.1.1" + Task = "(L1) Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.1" + Task = "(L1) Ensure 'Configure Automatic Updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.2" + Task = "(L1) Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.3" + Task = "(L1) Ensure 'Enable features introduced via servicing that are off by default' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "AllowTemporaryEnterpriseFeatureControl" ` + | Select-Object -ExpandProperty "AllowTemporaryEnterpriseFeatureControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.4" + Task = "(L1) Ensure 'Remove access to `"Pause updates`" feature' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "SetDisablePauseUXAccess" ` + | Select-Object -ExpandProperty "SetDisablePauseUXAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.1" + Task = "(L1) Ensure 'Manage preview builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "ManagePreviewBuildsPolicyValue" ` + | Select-Object -ExpandProperty "ManagePreviewBuildsPolicyValue" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.2 A" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdates" ` + | Select-Object -ExpandProperty "DeferFeatureUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.2 B" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferFeatureUpdatesPeriodInDays" + + if (($regValue -lt 180 -or $regValue -gt 365)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 180 and x <= 365" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.3 A" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdates" ` + | Select-Object -ExpandProperty "DeferQualityUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.3 B" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferQualityUpdatesPeriodInDays" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.4" + Task = "(L1) Ensure 'Enable optional updates' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "AllowOptionalContent" ` + | Select-Object -ExpandProperty "AllowOptionalContent" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.5.1.1" + Task = "(L1) Ensure 'Turn off toast notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.6.6.1.1" + Task = "(L2) Ensure 'Turn off Help Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Assistance\Client\1.0" ` + -Name "NoImplicitFeedback" ` + | Select-Object -ExpandProperty "NoImplicitFeedback" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.5.1" + Task = "(L1) Ensure 'Do not preserve zone information in file attachments' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.5.2" + Task = "(L1) Ensure 'Notify antivirus programs when opening attachments' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "ScanWithAntiVirus" ` + | Select-Object -ExpandProperty "ScanWithAntiVirus" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.1" + Task = "(L1) Ensure 'Configure Windows spotlight on lock screen' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "ConfigureWindowsSpotlight" ` + | Select-Object -ExpandProperty "ConfigureWindowsSpotlight" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.2" + Task = "(L1) Ensure 'Do not suggest third-party content in Windows spotlight' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.3" + Task = "(L2) Ensure 'Do not use diagnostic data for tailored experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableTailoredExperiencesWithDiagnosticData" ` + | Select-Object -ExpandProperty "DisableTailoredExperiencesWithDiagnosticData" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.4" + Task = "(L2) Ensure 'Turn off all Windows spotlight features' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsSpotlightFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsSpotlightFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.5" + Task = "(L1) Ensure 'Turn off Spotlight collection on Desktop' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableSpotlightCollectionOnDesktop" ` + | Select-Object -ExpandProperty "DisableSpotlightCollectionOnDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.26.1" + Task = "(L1) Ensure 'Prevent users from sharing files within their profile.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInplaceSharing" ` + | Select-Object -ExpandProperty "NoInplaceSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.40.1" + Task = "(L1) Ensure 'Turn off Windows Copilot' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot" ` + -Name "TurnOffWindowsCopilot" ` + | Select-Object -ExpandProperty "TurnOffWindowsCopilot" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.44.1" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled' (AlwaysInstallElevated)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.46.2.1" + Task = "(L2) Ensure 'Prevent Codec Download' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\WindowsMediaPlayer" ` + -Name "PreventCodecDownload" ` + | Select-Object -ExpandProperty "PreventCodecDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#SecurityOptions.ps1 new file mode 100644 index 0000000..a513d52 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#SecurityOptions.ps1 @@ -0,0 +1,130 @@ +[AuditTest] @{ + Id = "2.3.1.1" + Task = "(L1) Ensure 'Accounts: Guest account status' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.3" + Task = "(L1) Configure 'Accounts: Rename administrator account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption. Expected any other name than 'Administrator'" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.4" + Task = "(L1) Configure 'Accounts: Rename guest account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption. Expected any other name than 'Guest' or 'Gast'" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.1" + Task = "(L1) Ensure 'Network access: Allow anonymous SID/Name translation' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.6" + Task = "(L1) Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["ForceLogoffWhenHourExpire"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 1) { + return @{ + Message = "'ForceLogoffWhenHourExpire' currently set to: $setOption. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#UserRights.ps1 new file mode 100644 index 0000000..2ef5593 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-CIS-4.0.0#UserRights.ps1 @@ -0,0 +1,1509 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE") { + if ($name -eq "Enterprise Admins") { + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins") { + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + if ($sidAccount.Translate([System.Security.Principal.NTAccount]) -eq "NULL SID") { + return @{ + Account = $null + Sid = $sidAccount.Value + } + } + else { + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "2.2.1" + Task = "(L1) Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Remote Desktop Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.3" + Task = "(L1) Ensure 'Act as part of the operating system' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.4" + Task = "(L1) Ensure 'Adjust memory quotas for a process' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseQuotaPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseQuotaPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseQuotaPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.5" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.6" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators, Remote Desktop Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.7" + Task = "(L1) Ensure 'Back up files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.8" + Task = "(L1) Ensure 'Change the system time' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemtimePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemtimePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemtimePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.9" + Task = "(L1) Ensure 'Change the time zone' is set to 'Administrators, LOCAL SERVICE, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTimeZonePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTimeZonePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTimeZonePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.10" + Task = "(L1) Ensure 'Create a pagefile' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.11" + Task = "(L1) Ensure 'Create a token object' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.12" + Task = "(L1) Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.13" + Task = "(L1) Ensure 'Create permanent shared objects' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if ($hyperVStatus -ne "Enabled") { + [AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Configure 'Create symbolic links' [Hyper-V-Feature NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else { + [AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Configure 'Create symbolic links' [Hyper-V-Feature installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.15" + Task = "(L1) Ensure 'Debug programs' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + #No UserRights on System comparing to publisher recommendation + if ($null -eq $currentUserRights -and $identityAccounts.Count -gt 0) { + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if ($currentUserRights.Count -lt $identityAccounts.Count) { + $users = "" + foreach ($currentUser in $currentUserRights) { + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.16" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests, Local account'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-113" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.17" + Task = "(L1) Ensure 'Deny log on as a batch job' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.18" + Task = "(L1) Ensure 'Deny log on as a service' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyServiceLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Deny log on locally' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.20" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' to include 'Guests, Local account'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-113" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.21" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @() | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.22" + Task = "(L1) Ensure 'Force shutdown from a remote system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.23" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.24" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-6" + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.25" + Task = "(L1) Ensure 'Increase scheduling priority' is set to 'Administrators, Window Manager\Window Manager Group'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseBasePriorityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-90-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseBasePriorityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseBasePriorityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.26" + Task = "(L1) Ensure 'Load and unload device drivers' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.27" + Task = "(L1) Ensure 'Lock pages in memory' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.28" + Task = "(L2) Ensure 'Log on as a batch job' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBatchLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if ($hyperVStatus -ne "Enabled") { + [AuditTest] @{ + Id = "2.2.29" + Task = "(L2) Configure 'Log on as a service' [Hyper-V-Feature NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeServiceLogonRight"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeServiceLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else { + [AuditTest] @{ + Id = "2.2.29" + Task = "(L2) Configure 'Log on as a service' [Hyper-V-Feature installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeServiceLogonRight"] + $identityAccounts = @( + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if ($missingUsers.Count -gt 0) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.30" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.31" + Task = "(L1) Ensure 'Modify an object label' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRelabelPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRelabelPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRelabelPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.32" + Task = "(L1) Ensure 'Modify firmware environment values' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.33" + Task = "(L1) Ensure 'Perform volume maintenance tasks' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.34" + Task = "(L1) Ensure 'Profile single process' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.35" + Task = "(L1) Ensure 'Profile system performance' is set to 'Administrators, NT SERVICE\WdiServiceHost'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemProfilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemProfilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemProfilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.36" + Task = "(L1) Ensure 'Replace a process level token' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAssignPrimaryTokenPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAssignPrimaryTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAssignPrimaryTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.37" + Task = "(L1) Ensure 'Restore files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.38" + Task = "(L1) Ensure 'Shut down the system' is set to 'Administrators, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.39" + Task = "(L1) Ensure 'Take ownership of files or other objects' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#AccountPolicies.ps1 new file mode 100644 index 0000000..da0ac0e --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#AccountPolicies.ps1 @@ -0,0 +1,196 @@ +[AuditTest] @{ + Id = "AccountPolicy-361" + Task = "Ensure 'MinimumPasswordLength' is set to '14' character(s)." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 14) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-362" + Task = "The built-in Windows password complexity policy must be enabled." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-363" + Task = "The password history must be configured to 24 passwords remembered" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-364" + Task = "Ensure 'LockoutBadCount' is set to '10' invalid logon attempt(s)" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 10) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: 10" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-365" + Task = "Ensure 'Reset account lockout counter after' is set to '10 minutes'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 10) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: 10 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-366" + Task = "Ensure 'LockoutDuration' is set to '10 minutes'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 10) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: 10 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-367" + Task = "Reversible password encryption must be disabled." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#AuditPolicies.ps1 new file mode 100644 index 0000000..76a02f4 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#AuditPolicies.ps1 @@ -0,0 +1,1388 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "AuditPolicy-166" + Task = "Ensure 'Credential Validation' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-167" + Task = "Ensure 'Security Group Management' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-168" + Task = "Ensure 'User Account Management' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-169" + Task = "Ensure 'Plug and Play Events' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-170" + Task = "Ensure 'Process Creation' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-171" + Task = "Ensure 'Account Lockout' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-172" + Task = "Ensure 'Group Membership' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-173" + Task = "Ensure 'Logon' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-174" + Task = "Ensure 'Other Logon/Logoff Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-175" + Task = "Ensure 'Special Logon' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-176" + Task = "Ensure 'Detailed File Share' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-177" + Task = "Ensure 'File Share' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-178" + Task = "Ensure 'Other Object Access Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-179" + Task = "Ensure 'Removable Storage' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-180" + Task = "Ensure 'Audit Policy Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-181" + Task = "Ensure 'Authentication Policy Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-182" + Task = "Ensure 'MPSSVC Rule-Level Policy Change' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory MPSSVC Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "MPSSVC Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'MPSSVC Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-183" + Task = "Ensure 'Other Policy Change Events' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-184" + Task = "Ensure 'Sensitive Privilege Use' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-185" + Task = "Ensure 'Other System Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-186" + Task = "Ensure 'Security State Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-187" + Task = "Ensure 'Security System Extension' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-188" + Task = "Ensure 'System Integrity' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#RegistrySettings.ps1 new file mode 100644 index 0000000..0ab0432 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#RegistrySettings.ps1 @@ -0,0 +1,12011 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$avstatus = CheckForActiveAV +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "Registry-001" + Task = "Turn off Connect to suggested open hotspots and Connect to networks shared by my contacts" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config" ` + -Name "AutoConnectAllowedOEM" ` + | Select-Object -ExpandProperty "AutoConnectAllowedOEM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-002" + Task = "Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-003" + Task = "Ensure 'Turn off Autoplay' is set to 'All drives'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-004" + Task = "Ensure 'Turn off Internet download for Web publishing and online ordering wizards' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-005" + Task = "Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-006" + Task = "Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-007" + Task = "Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-008" + Task = "Local administrator accounts must have their privileged token filtered to prevent elevated privileges from being used over the network on domain systems." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-009" + Task = "Ensure 'Enable MPR notifications for the system' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableMPR" ` + | Select-Object -ExpandProperty "EnableMPR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-010" + Task = "Ensure 'Encryption Oracle Remediation' is set to 'Force Updated Clients'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-011" + Task = "Ensure 'Configure enhanced anti-spoofing' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-012" + Task = "Ensure 'Prevent downloading of enclosures' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-013" + Task = "Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-014" + Task = "Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-015" + Task = "Ensure 'Let Windows apps activate with voice while the system is locked' is set to 'Force Deny'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsActivateWithVoiceAboveLock" ` + | Select-Object -ExpandProperty "LetAppsActivateWithVoiceAboveLock" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-016" + Task = "Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-017" + Task = "Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-018" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '32768' (Application)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-019" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '196608' (Security)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-020" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '32768' (System)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-021" + Task = "Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-022" + Task = "Ensure 'Windows Game Recording and Broadcasting' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\GameDVR" ` + -Name "AllowGameDVR" ` + | Select-Object -ExpandProperty "AllowGameDVR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-023" + Task = "Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-024" + Task = "Ensure 'Configure registry policy processing' is set to '0'. (NoBackgroundPolicy)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-025" + Task = "Ensure 'Always install with elevated privileges' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-026" + Task = "Ensure 'Allow user control over installs' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-027" + Task = "Ensure 'Enumeration policy for external devices incompatible with Kernel DMA Protection' is set to 'Block all'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-028" + Task = "Ensure 'Enable insecure guest logons' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-029" + Task = "Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-030" + Task = "Set registry value '\\*\SYSVOL' to RequireMutualAuthentication=1, RequireIntegrity=1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if ( -not($regValue -match "RequireMutualAuthentication=1" -and $regValue -match "RequireIntegrity=1")) { + return @{ + Message = "Registry value is '$regValue'. Expected: RequireMutualAuthentication=1, RequireIntegrity=1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-031" + Task = "Set registry value '\\*\NETLOGON' to RequireMutualAuthentication=1, RequireIntegrity=1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if ( -not($regValue -match "RequireMutualAuthentication=1" -and $regValue -match "RequireIntegrity=1")) { + return @{ + Message = "Registry value is '$regValue'. Expected: RequireMutualAuthentication=1, RequireIntegrity=1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-032" + Task = "Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-033" + Task = "Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-034" + Task = "Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-035" + Task = "Ensure 'Turn on PowerShell Script Block Logging' is not set." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockInvocationLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockInvocationLogging" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-036" + Task = "Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-037" + Task = "Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-038" + Task = "Ensure 'Configure Windows SmartScreen' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-039" + Task = "Ensure 'Configure Windows Defender SmartScreen' is set to 'Block'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-040" + Task = "Ensure 'Allow Custom SSPs and APs to be loaded into LSASS' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "AllowCustomSSPsAPs" ` + | Select-Object -ExpandProperty "AllowCustomSSPsAPs" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-041" + Task = "Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-042" + Task = "Ensure 'Allow indexing of encrypted files' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-043" + Task = "Ensure 'Disallow Digest authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-044" + Task = "Ensure 'Allow unencrypted traffic' is set to 'Disabled'. (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-045" + Task = "Ensure 'Allow Basic authentication' is set to 'Disabled'. (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-046" + Task = "Ensure 'Allow unencrypted traffic' is set to 'Disabled'. (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-047" + Task = "Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'. (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-048" + Task = "Ensure 'Allow Basic authentication' is set to 'Disabled'. (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-049" + Task = "Ensure 'Notify Malicious' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "NotifyMalicious" ` + | Select-Object -ExpandProperty "NotifyMalicious" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-050" + Task = "Ensure 'Notify Password Reuse' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "NotifyPasswordReuse" ` + | Select-Object -ExpandProperty "NotifyPasswordReuse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-051" + Task = "Ensure 'Notify Unsafe App' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "NotifyUnsafeApp" ` + | Select-Object -ExpandProperty "NotifyUnsafeApp" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-052" + Task = "Ensure 'Service Enabled' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "ServiceEnabled" ` + | Select-Object -ExpandProperty "ServiceEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-053" + Task = "Ensure 'Turn off multicast name resolution' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-054" + Task = "Set registry value 'EnableNetBIOS' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableNetBIOS" ` + | Select-Object -ExpandProperty "EnableNetBIOS" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-055" + Task = "Ensure 'Turn off downloading of print drivers over HTTP' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-056" + Task = "Ensure 'Configure Redirection Guard' is set to 'Enabled: Redirection Guard Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "RedirectionGuardPolicy" ` + | Select-Object -ExpandProperty "RedirectionGuardPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-057" + Task = "Ensure 'Manage processing of Queue-specific files' is set to 'Enabled: Limit Queue-specific files to Color profiles'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "CopyFilesPolicy" ` + | Select-Object -ExpandProperty "CopyFilesPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-058" + Task = "Ensure 'Limits print driver installation to Administrators' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "RestrictDriverInstallationToAdministrators" ` + | Select-Object -ExpandProperty "RestrictDriverInstallationToAdministrators" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-059" + Task = "Set registry value 'RpcUseNamedPipeProtocol' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcUseNamedPipeProtocol" ` + | Select-Object -ExpandProperty "RpcUseNamedPipeProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-060" + Task = "Ensure 'Configure RPC connection settings: Use authentication for outgoing RPC connections' is set to 'Enabled: Default'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcAuthentication" ` + | Select-Object -ExpandProperty "RpcAuthentication" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-061" + Task = "Ensure 'Configure RPC listener settings: Protocols to allow for incoming RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcProtocols" ` + | Select-Object -ExpandProperty "RpcProtocols" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-062" + Task = "Set registry value 'ForceKerberosForRpc' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "ForceKerberosForRpc" ` + | Select-Object -ExpandProperty "ForceKerberosForRpc" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-063" + Task = "Ensure 'Configure RPC over TCP port' is set to 'Enabled: 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcTcpPort" ` + | Select-Object -ExpandProperty "RpcTcpPort" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-064" + Task = "Ensure 'Restrict Unauthenticated RPC clients' is set to 'Authenticated'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-065" + Task = "Solicited Remote Assistance - Set method for sending email invitations to 'Simple MAPI'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fUseMailto" ` + | Select-Object -ExpandProperty "fUseMailto" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-066" + Task = "Solicited Remote Assistance must not be allowed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-067" + Task = "Ensure 'Configure Solicited Remote Assistance' is not set (fAllowFullControl)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowFullControl" ` + | Select-Object -ExpandProperty "fAllowFullControl" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-068" + Task = "Ensure 'Configure Solicited Remote Assistance' is not set (MaxTicketExpiry)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxTicketExpiry" ` + | Select-Object -ExpandProperty "MaxTicketExpiry" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-069" + Task = "Ensure 'Configure Solicited Remote Assistance' is not set (MaxTicketExpiryUnits)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxTicketExpiryUnits" ` + | Select-Object -ExpandProperty "MaxTicketExpiryUnits" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-070" + Task = "Ensure 'Set client connection encryption level' is set to 'High Level'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-071" + Task = "Ensure 'Always prompt for password upon connection' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-072" + Task = "Ensure 'Do not allow drive redirection' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-073" + Task = "Ensure 'Do not allow passwords to be saved' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-074" + Task = "Ensure 'Require secure RPC communication' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-076" + Task = "Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" ` + -Name "DefaultOutboundAction" ` + | Select-Object -ExpandProperty "DefaultOutboundAction" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-077" + Task = "Ensure 'Windows Defender Firewall: Prohibit notifications' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" ` + -Name "DisableNotifications" ` + | Select-Object -ExpandProperty "DisableNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-078" + Task = "Ensure 'Windows Defender Firewall: Protect all network connections' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" ` + -Name "EnableFirewall" ` + | Select-Object -ExpandProperty "EnableFirewall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-079" + Task = "Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" ` + -Name "DefaultInboundAction" ` + | Select-Object -ExpandProperty "DefaultInboundAction" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-080" + Task = "Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" ` + -Name "LogDroppedPackets" ` + | Select-Object -ExpandProperty "LogDroppedPackets" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-081" + Task = "Ensure 'Windows Defender Firewall: Allow logging' is set to '16384' (LogFileSize)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" ` + -Name "LogFileSize" ` + | Select-Object -ExpandProperty "LogFileSize" + + if ($regValue -ne 16384) { + return @{ + Message = "Registry value is '$regValue'. Expected: 16384" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-082" + Task = "Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" ` + -Name "LogSuccessfulConnections" ` + | Select-Object -ExpandProperty "LogSuccessfulConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-083" + Task = "Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" ` + -Name "EnableFirewall" ` + | Select-Object -ExpandProperty "EnableFirewall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-084" + Task = "Private: Set registry value 'DisableNotifications' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" ` + -Name "DisableNotifications" ` + | Select-Object -ExpandProperty "DisableNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-085" + Task = "Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" ` + -Name "DefaultInboundAction" ` + | Select-Object -ExpandProperty "DefaultInboundAction" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-086" + Task = "Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" ` + -Name "DefaultOutboundAction" ` + | Select-Object -ExpandProperty "DefaultOutboundAction" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-087" + Task = "Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" ` + -Name "LogSuccessfulConnections" ` + | Select-Object -ExpandProperty "LogSuccessfulConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-088" + Task = "Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" ` + -Name "LogDroppedPackets" ` + | Select-Object -ExpandProperty "LogDroppedPackets" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-089" + Task = "Set registry value 'LogFileSize' to 16384." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" ` + -Name "LogFileSize" ` + | Select-Object -ExpandProperty "LogFileSize" + + if ($regValue -ne 16384) { + return @{ + Message = "Registry value is '$regValue'. Expected: 16384" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-090" + Task = "Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" ` + -Name "DefaultOutboundAction" ` + | Select-Object -ExpandProperty "DefaultOutboundAction" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-091" + Task = "Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" ` + -Name "EnableFirewall" ` + | Select-Object -ExpandProperty "EnableFirewall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-092" + Task = "Public: Set registry value 'DisableNotifications' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" ` + -Name "DisableNotifications" ` + | Select-Object -ExpandProperty "DisableNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-093" + Task = "Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" ` + -Name "AllowLocalIPsecPolicyMerge" ` + | Select-Object -ExpandProperty "AllowLocalIPsecPolicyMerge" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-094" + Task = "Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" ` + -Name "AllowLocalPolicyMerge" ` + | Select-Object -ExpandProperty "AllowLocalPolicyMerge" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-095" + Task = "Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" ` + -Name "DefaultInboundAction" ` + | Select-Object -ExpandProperty "DefaultInboundAction" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-096" + Task = "Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' set to '16,384'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" ` + -Name "LogFileSize" ` + | Select-Object -ExpandProperty "LogFileSize" + + if ($regValue -ne 16384) { + return @{ + Message = "Registry value is '$regValue'. Expected: 16384" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-097" + Task = "Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" ` + -Name "LogDroppedPackets" ` + | Select-Object -ExpandProperty "LogDroppedPackets" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-098" + Task = "Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" ` + -Name "LogSuccessfulConnections" ` + | Select-Object -ExpandProperty "LogSuccessfulConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-099" + Task = "Ensure 'Allow Windows Ink Workspace' is set to 'On, but disallow access above lock'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-100" + Task = "Ensure 'Enable local admin password management' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft Services\AdmPwd" ` + -Name "AdmPwdEnabled" ` + | Select-Object -ExpandProperty "AdmPwdEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-101" + Task = "Ensure 'Configures LSASS to run as a protected process' is set to 'Enabled: Enabled with UEFI Lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RunAsPPL" ` + | Select-Object -ExpandProperty "RunAsPPL" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-102" + Task = "Ensure 'Configure RPC packet level privacy setting for incoming connections' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print" ` + -Name "RpcAuthnLevelPrivacyEnabled" ` + | Select-Object -ExpandProperty "RpcAuthnLevelPrivacyEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-103" + Task = "Ensure 'WDigest Authentication (disabling may require KB2871997)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-104" + Task = "Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-105" + Task = "Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-106" + Task = "Ensure 'Configure SMB v1 server' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-107" + Task = "Ensure 'Configure SMB v1 client driver' is set to 'Disable driver (recommended)'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MrxSmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-108" + Task = "Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NoNameReleaseOnDemand" ` + | Select-Object -ExpandProperty "NoNameReleaseOnDemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-109" + Task = "Ensure 'NetBT NodeType configuration' is set to 'P-node (recommended)'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-110" + Task = "Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-111" + Task = "Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Highest protection, source routing is completely disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-112" + Task = "Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Highest protection, source routing is completely disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-113" + Task = "Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-114" + Task = "The machine inactivity limit must be set to 15 minutes, locking the system with the screensaver." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -ne 900)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 900" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-115" + Task = "Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-116" + Task = "Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-117" + Task = "Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-118" + Task = "Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-119" + Task = "Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-120" + Task = "Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-121" + Task = "Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-122" + Task = "The system must be configured to meet the minimum session security requirement for NTLM SSP-based clients." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if (($regValue -ne 537395200)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-123" + Task = "(ND, NE) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-124" + Task = "Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "allownullsessionfallback" ` + | Select-Object -ExpandProperty "allownullsessionfallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-125" + Task = "Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if (($regValue -ne 537395200)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-126" + Task = "Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-127" + Task = "Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-128" + Task = "Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "sealsecurechannel" ` + | Select-Object -ExpandProperty "sealsecurechannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-129" + Task = "Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-130" + Task = "Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-131" + Task = "Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-132" + Task = "Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-133" + Task = "Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-134" + Task = "Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-135" + Task = "User Account Control must run all administrators in Admin Approval Mode, enabling UAC." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-136" + Task = "Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-137" + Task = "User Account Control must be configured to detect application installations and prompt for elevation" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-138" + Task = "Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-139" + Task = "User Account Control must virtualize file and registry write failures to per-user locations." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-140" + Task = "Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-141" + Task = "Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictRemoteSAM" ` + | Select-Object -ExpandProperty "RestrictRemoteSAM" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-189" + Task = "Ensure 'Configure detection for potentially unwanted applications' is set to 'Enabled: Block'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-190" + Task = "Ensure 'Select cloud protection level' is set to 'Enabled:High blocking level'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\MpEngine" ` + -Name "MpCloudBlockLevel" ` + | Select-Object -ExpandProperty "MpCloudBlockLevel" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-191" + Task = "Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-192" + Task = "Ensure 'Turn off real-time protection' is set to 'Disabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-193" + Task = "Ensure 'Turn on script scanning' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableScriptScanning" ` + | Select-Object -ExpandProperty "DisableScriptScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-194" + Task = "Ensure 'Turn on behavior monitoring' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-195" + Task = "Ensure 'Scan removable drives' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-196" + Task = "Ensure 'Send file samples when further analysis is required' is set to 'Send safe samples'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SubmitSamplesConsent" ` + | Select-Object -ExpandProperty "SubmitSamplesConsent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-197" + Task = "Ensure 'Join Microsoft MAPS' is set to 'Advanced MAPS'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-198" + Task = "Ensure 'Configure the 'Block at First Sight' feature' is set to 'Enabled'." + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "DisableBlockAtFirstSeen" ` + | Select-Object -ExpandProperty "DisableBlockAtFirstSeen" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-199" + Task = "Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-200" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from injecting code into other processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-201" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating executable content'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-202" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating child processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-203" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Block Win32 API calls from Office macro'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-204" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Block execution of potentially obfuscated scripts'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-205" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Block JavaScript or VBScript from launching downloaded executable content'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-206" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Block executable content from email client and webmail'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-207" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Block credential stealing from the Windows local security authority subsystem (lsass.exe))'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-208" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Block untrusted and unsigned processes that run from USB' is configured" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-209" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Block Office communication application from creating child processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-210" + Task = "(ND, NE) Ensure 'Configure Attack Surface Reduction rules: Block Adobe Reader from creating child processes'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-211" + Task = "Ensure 'Configure Attack Surface Reduction rules: Use advanced protection against ransomware'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" ` + -Name "c1db55ab-c21a-4637-bb3f-a12568109d35" ` + | Select-Object -ExpandProperty "c1db55ab-c21a-4637-bb3f-a12568109d35" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-212" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block persistence through WMI event subscription'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-213" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block abuse of exploited vulnerable signed drivers'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-214" + Task = "Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Block'" + Test = { + try { + if ($avstatus) { + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-215" + Task = "Ensure 'Remove `"Run this time`" button for outdated ActiveX controls in Internet Explorer ' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "RunThisTimeEnabled" ` + | Select-Object -ExpandProperty "RunThisTimeEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-216" + Task = "Ensure 'Turn off blocking of outdated ActiveX controls for Internet Explorer' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "VersionCheckEnabled" ` + | Select-Object -ExpandProperty "VersionCheckEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-217" + Task = "Ensure 'Allow software to run or install even if the signature is invalid' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "RunInvalidSignatures" ` + | Select-Object -ExpandProperty "RunInvalidSignatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-218" + Task = "Set registry value 'CheckExeSignatures' to yes." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "CheckExeSignatures" ` + | Select-Object -ExpandProperty "CheckExeSignatures" + + if ($regValue -ne "yes") { + return @{ + Message = "Registry value is '$regValue'. Expected: yes" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-219" + Task = "Ensure 'Turn on 64-bit tab processes when running in Enhanced Protected Mode on 64-bit versions of Windows' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation64Bit" ` + | Select-Object -ExpandProperty "Isolation64Bit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-220" + Task = "Ensure 'Do not allow ActiveX controls to run in Protected Mode when Enhanced Protected Mode is enabled' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "DisableEPMCompat" ` + | Select-Object -ExpandProperty "DisableEPMCompat" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-221" + Task = "Set registry value 'Isolation' to PMEM." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation" ` + | Select-Object -ExpandProperty "Isolation" + + if ($regValue -ne "PMEM") { + return @{ + Message = "Registry value is '$regValue'. Expected: PMEM" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-222" + Task = "Ensure 'Internet Explorer Processes for MK protocol' is not enabled (Reserved)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-223" + Task = "Ensure 'Internet Explorer Processes for MK protocol' is not enabled (iexplore.exe)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-224" + Task = " Ensure 'Internet Explorer Processes for MK protocol' is not enabled (explorer.exe)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-225" + Task = "Set registry value 'explorer.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-226" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_MIME_HANDLING)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-227" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_MIME_HANDLING)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-228" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_MIME_SNIFFING)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-229" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_MIME_SNIFFING)" + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-230" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_MIME_SNIFFING)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-231" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_RESTRICT_ACTIVEXINSTALL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-232" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_RESTRICT_ACTIVEXINSTALL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-233" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_RESTRICT_ACTIVEXINSTALL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-234" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_RESTRICT_FILEDOWNLOAD)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-235" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_RESTRICT_FILEDOWNLOAD)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-236" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_RESTRICT_FILEDOWNLOAD)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-237" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_SECURITYBAND)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-238" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_SECURITYBAND)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-239" + Task = "Set 'Notification bar' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-240" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_WINDOW_RESTRICTIONS)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-241" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_WINDOW_RESTRICTIONS)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-242" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_WINDOW_RESTRICTIONS)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-243" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_ZONE_ELEVATION)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-244" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_ZONE_ELEVATION)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-245" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_ZONE_ELEVATION)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-246" + Task = "Set 'Prevent bypassing SmartScreen Filter warnings about files that are not commonly downloaded from the Internet' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverrideAppRepUnknown" ` + | Select-Object -ExpandProperty "PreventOverrideAppRepUnknown" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-247" + Task = "Set 'Prevent Bypassing SmartScreen Filter Warnings' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-248" + Task = "Ensure 'Prevent managing SmartScreen Filter' is set to 'On'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-249" + Task = "Set 'Turn off Crash Detection' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Restrictions" ` + -Name "NoCrashDetection" ` + | Select-Object -ExpandProperty "NoCrashDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-250" + Task = "Ensure 'Turn off the Security Settings Check feature' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security" ` + -Name "DisableSecuritySettingsCheck" ` + | Select-Object -ExpandProperty "DisableSecuritySettingsCheck" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-251" + Task = "Ensure 'Prevent per-user installation of ActiveX controls' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security\ActiveX" ` + -Name "BlockNonAdminActiveXInstall" ` + | Select-Object -ExpandProperty "BlockNonAdminActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-252" + Task = "Ensure 'Specify use of ActiveX Installer Service for installation of ActiveX controls' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AxInstaller" ` + -Name "OnlyUseAXISForActiveXInstall" ` + | Select-Object -ExpandProperty "OnlyUseAXISForActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-253" + Task = "Set 'Security Zones: Do not allow users to add/delete sites' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_zones_map_edit" ` + | Select-Object -ExpandProperty "Security_zones_map_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-254" + Task = "Set 'Security Zones: Do not allow users to change policies' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_options_edit" ` + | Select-Object -ExpandProperty "Security_options_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-255" + Task = "Set 'Security Zones: Use only machine settings' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_HKLM_only" ` + | Select-Object -ExpandProperty "Security_HKLM_only" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-256" + Task = "Ensure 'Check for server certificate revocation' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "CertificateRevocation" ` + | Select-Object -ExpandProperty "CertificateRevocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-257" + Task = "Ensure 'Prevent ignoring certificate errors' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "PreventIgnoreCertErrors" ` + | Select-Object -ExpandProperty "PreventIgnoreCertErrors" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-258" + Task = "Set 'Turn on certificate address mismatch warning' to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "WarnOnBadCertRecving" ` + | Select-Object -ExpandProperty "WarnOnBadCertRecving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-259" + Task = "Ensure 'Allow fallback to SSL 3.0 (Internet Explorer)' is set to 'No Sites'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "EnableSSL3Fallback" ` + | Select-Object -ExpandProperty "EnableSSL3Fallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-260" + Task = "Ensure 'Turn off encryption support' is set to 'Use TLS 1.1 and TLS 1.2'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "SecureProtocols" ` + | Select-Object -ExpandProperty "SecureProtocols" + + if (($regValue -ne 2560)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2560" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-261" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Lockdown_Zones/0)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-262" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Lockdown_Zones/1)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-263" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Lockdown_Zones/2)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-264" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. (Lockdown_Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\3" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-265" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. (Lockdown_Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-266" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Lockdown_Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-267" + Task = "Ensure 'Intranet Sites: Include all network paths (UNCs)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap" ` + -Name "UNCAsIntranet" ` + | Select-Object -ExpandProperty "UNCAsIntranet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-268" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Zones/0)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-269" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'. (Zones/0)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-270" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'. (Zones/1)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-271" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'. (Zones/1)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-272" + Task = "Ensure 'Java permissions' is set to 'High safety'. (Zones/1)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if (($regValue -ne 65536)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-273" + Task = "Ensure 'Java permissions' is set to 'High safety'. (Zones/2)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if (($regValue -ne 65536)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-274" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'. (Zones/2)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-275" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'. (Zones/2)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-276" + Task = "Ensure 'Run .NET Framework-reliant components signed with Authenticode' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-277" + Task = "Ensure 'Allow script-initiated windows without size or position constraints' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-278" + Task = "Ensure 'Allow drag and drop or copy and paste files' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-279" + Task = "Ensure 'Include local path when user is uploading files to a server' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-280" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-281" + Task = "Ensure 'Access data sources across domains' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-282" + Task = "Ensure 'Launching applications and files in an IFRAME' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-283" + Task = "Ensure 'Automatic prompting for file downloads' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-284" + Task = "Ensure 'Allow scriptlets' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-285" + Task = "Ensure 'Allow scripting of Internet Explorer WebBrowser controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-286" + Task = "Ensure 'Use Pop-up Blocker' is set to 'Enable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-287" + Task = "Ensure 'Turn on Protected Mode' is set to 'Enable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-288" + Task = "Ensure 'Allow updates to status bar via script' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-289" + Task = "Ensure 'Userdata persistence' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-290" + Task = "Ensure 'Allow loading of XAML files' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-291" + Task = "Ensure 'Run .NET Framework-reliant components not signed with Authenticode' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-292" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-293" + Task = "Ensure 'Download signed ActiveX controls' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-294" + Task = "Ensure 'Logon options' is set to 'Prompt for user name and password'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if (($regValue -ne 65536)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-295" + Task = "Ensure 'Enable dragging of content from different domains within a window' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-296" + Task = "Ensure 'Download unsigned ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-297" + Task = "Ensure 'Allow only approved domains to use ActiveX controls without prompt' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-298" + Task = "Ensure 'Allow cut, copy or paste operations from the clipboard via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-299" + Task = "Ensure 'Turn on Cross-Site Scripting Filter' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-300" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-301" + Task = "Ensure 'Navigate windows and frames across different domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-302" + Task = "Ensure 'Enable dragging of content from different domains across windows' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-303" + Task = "Ensure 'Web sites in less privileged Web content zones can navigate into this zone' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-304" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-305" + Task = "Ensure 'Show security warning for potentially unsafe files' is set to 'Prompt'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-306" + Task = "Ensure 'Allow only approved domains to use the TDC ActiveX control' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120c" ` + | Select-Object -ExpandProperty "120c" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-307" + Task = "Set registry value '140C' to 3. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "140C" ` + | Select-Object -ExpandProperty "140C" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-308" + Task = "Ensure 'Allow META REFRESH' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1608" ` + | Select-Object -ExpandProperty "1608" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-309" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-310" + Task = "Ensure 'Download signed ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-311" + Task = "Ensure 'Navigate windows and frames across different domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-312" + Task = "Ensure 'Allow only approved domains to use ActiveX controls without prompt' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-313" + Task = "Ensure 'Use Pop-up Blocker' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-314" + Task = "Ensure 'Download unsigned ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-315" + Task = "Ensure 'Userdata persistence' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-316" + Task = "Ensure 'Allow cut, copy or paste operations from the clipboard via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-317" + Task = "Ensure 'Include local path when user is uploading files to a server' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-318" + Task = "Ensure 'Access data sources across domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-319" + Task = "Ensure 'Allow script-initiated windows without size or position constraints' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-320" + Task = "Ensure 'Run .NET Framework-reliant components not signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-321" + Task = "Ensure 'Automatic prompting for file downloads' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-322" + Task = "Ensure 'Allow binary and script behaviors' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2000" ` + | Select-Object -ExpandProperty "2000" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-323" + Task = "Ensure 'Scripting of Java applets' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1402" ` + | Select-Object -ExpandProperty "1402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-324" + Task = "Ensure 'Allow file downloads' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1803" ` + | Select-Object -ExpandProperty "1803" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-325" + Task = "Ensure 'Allow loading of XAML files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-326" + Task = "Ensure 'Allow active scripting' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1400" ` + | Select-Object -ExpandProperty "1400" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-327" + Task = "Ensure 'Logon options' is set to 'Anonymous logon'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-328" + Task = "Ensure 'Run .NET Framework-reliant components signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-329" + Task = "Ensure 'Turn on Protected Mode' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-330" + Task = "Ensure 'Turn on Cross-Site Scripting Filter' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-331" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-332" + Task = "Ensure 'Allow scriptlets' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-333" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-334" + Task = "Ensure 'Allow scripting of Internet Explorer WebBrowser controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-335" + Task = "Ensure 'Enable dragging of content from different domains within a window' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-336" + Task = "Ensure 'Allow drag and drop or copy and paste files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-337" + Task = "Ensure 'Allow updates to status bar via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-338" + Task = "Ensure 'Enable dragging of content from different domains across windows' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-339" + Task = "Ensure 'Script ActiveX controls marked safe for scripting' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1405" ` + | Select-Object -ExpandProperty "1405" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-340" + Task = "Ensure 'Web sites in less privileged Web content zones can navigate into this zone' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-341" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-342" + Task = "Ensure 'Run ActiveX controls and plugins' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1200" ` + | Select-Object -ExpandProperty "1200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-343" + Task = "Ensure 'Launching applications and files in an IFRAME' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-344" + Task = "Ensure 'Show security warning for potentially unsafe files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-345" + Task = "Ensure 'Allow only approved domains to use the TDC ActiveX control' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120c" ` + | Select-Object -ExpandProperty "120c" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-346" + Task = "Set registry value '140C' to 3. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "140C" ` + | Select-Object -ExpandProperty "140C" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-347" + Task = "Set 'Turn on the auto-complete feature for user names and passwords on forms' to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "FormSuggest Passwords" ` + | Select-Object -ExpandProperty "FormSuggest Passwords" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-348" + Task = "Ensure 'Turn on the auto-complete feature for user names and passwords on forms' is set to 'no'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "FormSuggest PW Ask" ` + | Select-Object -ExpandProperty "FormSuggest PW Ask" + + if ($regValue -ne "no") { + return @{ + Message = "Registry value is '$regValue'. Expected: no" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-349" + Task = "Set registry value 'FormSuggest Passwords' to no." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "FormSuggest Passwords" ` + | Select-Object -ExpandProperty "FormSuggest Passwords" + + if ($regValue -ne "no") { + return @{ + Message = "Registry value is '$regValue'. Expected: no" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-351" + Task = "Ensure 'Allow enhanced PINs for startup' is set 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseEnhancedPin" ` + | Select-Object -ExpandProperty "UseEnhancedPin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-352" + Task = "Set registry value 'RDVDenyCrossOrg' to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVDenyCrossOrg" ` + | Select-Object -ExpandProperty "RDVDenyCrossOrg" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-353" + Task = "Ensure 'Disable new DMA devices when this computer is locked' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "DisableExternalDMAUnderLock" ` + | Select-Object -ExpandProperty "DisableExternalDMAUnderLock" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-354" + Task = "Ensure 'Allow Standby States (S1-S3) When Sleeping (On Battery)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-355" + Task = "Ensure 'Allow Standby States (S1-S3) When Sleeping (Plugged In)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-356" + Task = "Ensure 'Prevent installation of devices using drivers that match these device setup classes' set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClasses" ` + | Select-Object -ExpandProperty "DenyDeviceClasses" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-357" + Task = "Ensure 'Prevent installation of devices using drivers that match these device setup classes' set to 'Also apply to matching devices that are already installed. (True) '." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClassesRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceClassesRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-358" + Task = "Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the SBP2 Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "{d48179be-ec20-11d1-b6b8-00c04fa372a7}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {d48179be-ec20-11d1-b6b8-00c04fa372a7}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-359" + Task = "Ensure 'Deny write access to removable drives not protected by BitLocker' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\Microsoft\FVE" ` + -Name "RDVDenyWriteAccess" ` + | Select-Object -ExpandProperty "RDVDenyWriteAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-368" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-369" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Secure Boot'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if ($regValue -eq 3) { + return @{ + Message = "Set to 'Secure Boot and DMA Protection' which is more secure." + Status = "True" + } + } + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-370" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled with UEFI lock'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-371" + Task = "Ensure 'Turn On Virtualization Based Security: Require UEFI Memory Attributes Table' is set to 'True (checked)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HVCIMATRequired" ` + | Select-Object -ExpandProperty "HVCIMATRequired" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-372" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled with UEFI lock'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-373" + Task = "Ensure 'Turn On Virtualization Based Security: Secure Launch Configuration' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureSystemGuardLaunch" ` + | Select-Object -ExpandProperty "ConfigureSystemGuardLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-374" + Task = "Ensure 'Turn On Virtualization Based Security: Kernel-mode Hardware-enforced Stack Protection' is set to 'Enabled: Enabled in enforcement mode'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureKernelShadowStacksLaunch" ` + | Select-Object -ExpandProperty "ConfigureKernelShadowStacksLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-375" + Task = "Ensure 'Do not suggest third-party content in Windows spotlight' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-376" + Task = "Toast notifications to the lock screen must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#SecurityOptions.ps1 new file mode 100644 index 0000000..64418af --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#SecurityOptions.ps1 @@ -0,0 +1,26 @@ +[AuditTest] @{ + Id = "SecurityOption-142" + Task = "Anonymous SID/Name translation must not be allowed." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#UserRights.ps1 new file mode 100644 index 0000000..60fbc6b --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Microsoft-22H2#UserRights.ps1 @@ -0,0 +1,875 @@ +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and + (Get-WindowsOptionalFeature -Online -FeatureName "Microsoft-Hyper-V").State -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "UserRight-143" + Task = "Ensure 'Manage auditing and security log' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-144" + Task = "Ensure 'Restore files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-145" + Task = "Ensure 'Take ownership of files or other objects' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-146" + Task = "Ensure 'Back up files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-147" + Task = "Ensure 'Deny log on through Remote Desktop Services' to include 'Local account'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeDenyRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-148" + Task = "Ensure 'Create permanent shared objects' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-149" + Task = "Ensure 'Perform volume maintenance tasks' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-150" + Task = "Ensure 'Load and unload device drivers' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-151" + Task = "Ensure 'SeLockMemoryPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-152" + Task = "Ensure 'Deny access to this computer from the network' is set to 'Local account'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeDenyNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-153" + Task = "Ensure 'Access this computer from the network' is set to 'Administrators, Remote Desktop Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-154" + Task = "Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE' [IIS Role NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-155" + Task = "Ensure 'Create a token object' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-156" + Task = "Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-157" + Task = "Ensure 'Modify firmware environment values' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-158" + Task = "The Create a pagefile user right must only be assigned to the Administrators group." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-159" + Task = "Ensure 'Allow log on locally' is set to 'Administrators, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-160" + Task = "Ensure 'Force shutdown from a remote system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-161" + Task = "Ensure 'Debug programs' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDebugPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-162" + Task = "Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-163" + Task = "Ensure 'Profile single process' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-164" + Task = "Ensure 'Act as part of the operating system' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-165" + Task = "Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#AccountPolicies.ps1 new file mode 100644 index 0000000..01118ef --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#AccountPolicies.ps1 @@ -0,0 +1,255 @@ +[AuditTest] @{ + Id = "1.1.1" + Task = "(L1) Ensure 'Enforce password history' is set to '24 or more password(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "(L1) Ensure 'Maximum password age' is set to '365 or fewer days, but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 365 -or $setPolicy -le 0)) { + if($setPolicy -eq -1){ #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 365 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "(L1) Ensure 'Minimum password age' is set to '1 or more day(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 1)) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "(L1) Ensure 'Minimum password length' is set to '14 or more character(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.5" + Task = "(L1) Ensure 'Password must meet complexity requirements' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.7" + Task = "(L1) Ensure 'Store passwords using reversible encryption' is set to 'Disabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "(L1) Ensure 'Account lockout duration' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15 -or $setPolicy -gt 99999)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15 minutes and x <= 99999 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "(L1) Ensure 'Account lockout threshold' is set to '5 or fewer invalid logon attempt(s), but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 5 -or $setPolicy -le 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 5 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.4" + Task = "(L1) Ensure 'Reset account lockout counter after' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 99999 -or $setPolicy -lt 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x <= 99999 minutes and x >= 15 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#AuditPolicies.ps1 new file mode 100644 index 0000000..01bc89f --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#AuditPolicies.ps1 @@ -0,0 +1,1616 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "17.1.1" + Task = "(L1) Ensure 'Audit Credential Validation' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.1" + Task = "(L1) Ensure 'Audit Application Group Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Application Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Application Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Application Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.2" + Task = "(L1) Ensure 'Audit Security Group Management' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.3" + Task = "(L1) Ensure 'Audit User Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.1" + Task = "(L1) Ensure 'Audit PNP Activity' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.2" + Task = "(L1) Ensure 'Audit Process Creation' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.1" + Task = "(L1) Ensure 'Audit Account Lockout' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.2" + Task = "(L1) Ensure 'Audit Group Membership' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.3" + Task = "(L1) Ensure 'Audit Logoff' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.4" + Task = "(L1) Ensure 'Audit Logon' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.5" + Task = "(L1) Ensure 'Audit Other Logon/Logoff Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.6" + Task = "(L1) Ensure 'Audit Special Logon' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.1" + Task = "(L1) Ensure 'Audit Detailed File Share' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.2" + Task = "(L1) Ensure 'Audit File Share' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.3" + Task = "(L1) Ensure 'Audit Other Object Access Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.4" + Task = "(L1) Ensure 'Audit Removable Storage' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.1" + Task = "(L1) Ensure 'Audit Audit Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.2" + Task = "(L1) Ensure 'Audit Authentication Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.3" + Task = "(L1) Ensure 'Audit Authorization Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.4" + Task = "(L1) Ensure 'Audit MPSSVC Rule-Level Policy Change' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Mpssvc Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Mpssvc Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Mpssvc Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.5" + Task = "(L1) Ensure 'Audit Other Policy Change Events' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.8.1" + Task = "(L1) Ensure 'Audit Sensitive Privilege Use' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.1" + Task = "(L1) Ensure 'Audit IPsec Driver' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Ipsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Ipsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Ipsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.2" + Task = "(L1) Ensure 'Audit Other System Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.3" + Task = "(L1) Ensure 'Audit Security State Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.4" + Task = "(L1) Ensure 'Audit Security System Extension' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.5" + Task = "(L1) Ensure 'Audit System Integrity' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#RegistrySettings.ps1 new file mode 100644 index 0000000..8daef46 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#RegistrySettings.ps1 @@ -0,0 +1,16049 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$avstatus = CheckForActiveAV +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "1.1.6" + Task = "(L1) Ensure 'Relax minimum password length limits' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SAM" ` + -Name "RelaxMinimumPasswordLengthLimits" ` + | Select-Object -ExpandProperty "RelaxMinimumPasswordLengthLimits" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.1" + Task = "(L1) Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "NoConnectedUser" ` + | Select-Object -ExpandProperty "NoConnectedUser" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.3" + Task = "(L1) Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.1" + Task = "(L1) Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.2" + Task = "(L1) Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\LSA" ` + -Name "CrashOnAuditFail" ` + | Select-Object -ExpandProperty "CrashOnAuditFail" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4.1" + Task = "(L2) Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.1" + Task = "(L1) Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.2" + Task = "(L1) Ensure 'Interactive logon: Don't display last signed-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.3" + Task = "(BL) Ensure 'Interactive logon: Machine account lockout threshold' is set to '10 or fewer invalid logon attempts, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MaxDevicePasswordFailedAttempts" ` + | Select-Object -ExpandProperty "MaxDevicePasswordFailedAttempts" + + if (($regValue -gt 10 -or $regValue -le 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 10 and x > 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.4" + Task = "(L1) Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.5" + Task = "(L1) Configure 'Interactive logon: Message text for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.6" + Task = "(L1) Configure 'Interactive logon: Message title for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.7" + Task = "(L1) Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if (($regValue -gt 14 -or $regValue -lt 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 14 and x >= 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.8" + Task = "(L1) Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -notmatch "^(1|2|3)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(1|2|3)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.8.1" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.2" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.3" + Task = "(L1) Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.1" + Task = "(L1) Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if (($regValue -gt 15)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.2" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.3" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.4" + Task = "(L1) Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "enableforcedlogoff" ` + | Select-Object -ExpandProperty "enableforcedlogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.5" + Task = "(L1) Ensure 'Microsoft network server: Server SPN target name validation level' is set to 1 - 'Accept if provided by client' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "SMBServerNameHardeningLevel" ` + | Select-Object -ExpandProperty "SMBServerNameHardeningLevel" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.2" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.3" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.4" + Task = "(L1) Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.5" + Task = "(L1) Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.6" + Task = "(L1) Ensure 'Network access: Named Pipes that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.7" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\ProductOptions" + "System\CurrentControlSet\Control\Server Applications" + "Software\Microsoft\Windows NT\CurrentVersion" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\ProductOptions System\CurrentControlSet\Control\Server Applications Software\Microsoft\Windows NT\CurrentVersion" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.8" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9" + Task = "(L1) Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.10" + Task = "(L1) Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "restrictremotesam" ` + | Select-Object -ExpandProperty "restrictremotesam" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.11" + Task = "(L1) Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionShares" ` + | Select-Object -ExpandProperty "NullSessionShares" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.12" + Task = "(L1) Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.1" + Task = "(L1) Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.2" + Task = "(L1) Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.3" + Task = "(L1) Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.4" + Task = "(L1) Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.5" + Task = "(L1) Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.7" + Task = "(L1) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.8" + Task = "(L1) Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.9" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.10" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.14.1" + Task = "(L2) Ensure 'System cryptography: Force strong key protection for user keys stored on the computer' is set to 1 - 'User is prompted when the key is first used' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Cryptography" ` + -Name "ForceKeyProtection" ` + | Select-Object -ExpandProperty "ForceKeyProtection" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.1" + Task = "(L1) Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.2" + Task = "(L1) Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.1" + Task = "(L1) Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.2" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.3" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.4" + Task = "(L1) Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.5" + Task = "(L1) Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.6" + Task = "(L1) Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.7" + Task = "(L1) Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.8" + Task = "(L1) Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1" + Task = "(L2) Ensure 'Bluetooth Audio Gateway Service (BTAGService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTAGService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2" + Task = "(L2) Ensure 'Bluetooth Support Service (bthserv)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bthserv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.3" + Task = "(L1) Ensure 'Computer Browser (Browser)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.4" + Task = "(L2) Ensure 'Downloaded Maps Manager (MapsBroker)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MapsBroker" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.5" + Task = "(L2) Ensure 'Geolocation Service (lfsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lfsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.6" + Task = "(L1) Ensure 'IIS Admin Service (IISADMIN)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IISADMIN" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.7" + Task = "(L1) Ensure 'Infrared monitor service (irmon)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\irmon" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.8" + Task = "(L1) Ensure 'Internet Connection Sharing (ICS) (SharedAccess)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.9" + Task = "(L2) Ensure 'Link-Layer Topology Discovery Mapper (lltdsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lltdsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.10" + Task = "(L1) Ensure 'LxssManager (LxssManager)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LxssManager" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.11" + Task = "(L1) Ensure 'Microsoft FTP Service (FTPSVC)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FTPSVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.12" + Task = "(L2) Ensure 'Microsoft iSCSI Initiator Service (MSiSCSI)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSiSCSI" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.13" + Task = "(L1) Ensure 'OpenSSH SSH Server (sshd)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sshd" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.14" + Task = "(L2) Ensure 'Peer Name Resolution Protocol (PNRPsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.15" + Task = "(L2) Ensure 'Peer Networking Grouping (p2psvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2psvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.16" + Task = "(L2) Ensure 'Peer Networking Identity Manager (p2pimsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2pimsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.17" + Task = "(L2) Ensure 'PNRP Machine Name Publication Service (PNRPAutoReg)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPAutoReg" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.18" + Task = "(L2) Ensure 'Print Spooler (Spooler)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.19" + Task = "(L2) Ensure 'Problem Reports and Solutions Control Panel Support (wercplsupport)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wercplsupport" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.20" + Task = "(L2) Ensure 'Remote Access Auto Connection Manager (RasAuto)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasAuto" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.21" + Task = "(L2) Ensure 'Remote Desktop Configuration (SessionEnv)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SessionEnv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.22" + Task = "(L2) Ensure 'Remote Desktop Services (TermService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.23" + Task = "(L2) Ensure 'Remote Desktop Services UserMode Port Redirector (UmRdpService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UmRdpService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.24" + Task = "(L1) Ensure 'Remote Procedure Call (RPC) Locator (RpcLocator)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcLocator" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.25" + Task = "(L2) Ensure 'Remote Registry (RemoteRegistry)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteRegistry" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.26" + Task = "(L1) Ensure 'Routing and Remote Access (RemoteAccess)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.27" + Task = "(L2) Ensure 'Server (LanmanServer)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.28" + Task = "(L1) Ensure 'Simple TCP/IP Services (simptcp)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\simptcp" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.29" + Task = "(L2) Ensure 'SNMP Service (SNMP)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SNMP" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.30" + Task = "(L1) Ensure 'Special Administration Console Helper (sacsvr)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sacsvr" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.31" + Task = "(L1) Ensure 'SSDP Discovery (SSDPSRV)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SSDPSRV" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.32" + Task = "(L1) Ensure 'UPnP Device Host (upnphost)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\upnphost" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.33" + Task = "(L1) Ensure 'Web Management Service (WMSvc)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.34" + Task = "(L2) Ensure 'Windows Error Reporting Service (WerSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WerSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.35" + Task = "(L2) Ensure 'Windows Event Collector (Wecsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Wecsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.36" + Task = "(L1) Ensure 'Windows Media Player Network Sharing Service (WMPNetworkSvc)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMPNetworkSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.37" + Task = "(L1) Ensure 'Windows Mobile Hotspot Service (icssvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\icssvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.38" + Task = "(L2) Ensure 'Windows Push Notifications System Service (WpnService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WpnService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.39" + Task = "(L2) Ensure 'Windows PushToInstall Service (PushToInstall)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PushToInstall" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.40" + Task = "(L2) Ensure 'Windows Remote Management (WS-Management) (WinRM)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinRM" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.41" + Task = "(L1) Ensure 'World Wide Web Publishing Service (W3SVC)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.42" + Task = "(L1) Ensure 'Xbox Accessory Management Service (XboxGipSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxGipSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.43" + Task = "(L1) Ensure 'Xbox Live Auth Manager (XblAuthManager)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblAuthManager" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.44" + Task = "(L1) Ensure 'Xbox Live Game Save (XblGameSave)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblGameSave" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.45" + Task = "(L1) Ensure 'Xbox Live Networking Service (XboxNetApiSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxNetApiSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.2.1" + Task = "(L1) Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.2" + Task = "(L1) Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.3" + Task = "(L1) Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.4" + Task = "(L1) Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.5" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\privatefw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\privatefw.log"; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.6" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.7" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.8" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.1" + Task = "(L1) Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.2" + Task = "(L1) Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.3" + Task = "(L1) Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.4" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.5" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.6" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.7" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\publicfw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\publicfw.log"; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.8" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.9" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.10" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "18.1.1.1" + Task = "(L1) Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.1.2" + Task = "(L1) Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.2.2" + Task = "(L1) Ensure 'Allow users to enable online speech recognition services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "AllowInputPersonalization" ` + | Select-Object -ExpandProperty "AllowInputPersonalization" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.3" + Task = "(L2) Ensure 'Allow Online Tips' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "AllowOnlineTips" ` + | Select-Object -ExpandProperty "AllowOnlineTips" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.1" + Task = "(L1) Ensure 'Configure RPC packet level privacy setting for incoming connections' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print" ` + -Name "RpcAuthnLevelPrivacyEnabled" ` + | Select-Object -ExpandProperty "RpcAuthnLevelPrivacyEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.2" + Task = "(L1) Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.3" + Task = "(L1) Ensure 'Configure SMB v1 server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.4" + Task = "(L1) Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.5" + Task = "(L1) Ensure 'NetBT NodeType configuration' is set to 'Enabled: P-node (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.6" + Task = "(L1) Ensure 'WDigest Authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.1" + Task = "(L1) Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.2" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.3" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.4" + Task = "(L2) Ensure 'MSS: (DisableSavePassword) Prevent the dial-up password from being saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\RasMan\Parameters" ` + -Name "disablesavepassword" ` + | Select-Object -ExpandProperty "disablesavepassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.5" + Task = "(L1) Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.6" + Task = "(L2) Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "KeepAliveTime" ` + | Select-Object -ExpandProperty "KeepAliveTime" + + if ($regValue -ne 300000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 300000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.7" + Task = "(L1) Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.8" + Task = "(L2) Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "PerformRouterDiscovery" ` + | Select-Object -ExpandProperty "PerformRouterDiscovery" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.9" + Task = "(L1) Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.10" + Task = "(L1) Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScreenSaverGracePeriod" ` + | Select-Object -ExpandProperty "ScreenSaverGracePeriod" + + if ($regValue -notmatch "^[0-5]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[0-5]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.11" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.12" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.13" + Task = "(L1) Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security" ` + -Name "WarningLevel" ` + | Select-Object -ExpandProperty "WarningLevel" + + if (($regValue -gt 90)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 90" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.1" + Task = "(L1) Ensure 'Configure DNS over HTTPS (DoH) name resolution' is set to 'Enabled: Allow DoH' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "DoHPolicy" ` + | Select-Object -ExpandProperty "DoHPolicy" + + if (($regValue -ne 2) -and ($regValue -ne 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2 or x == 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.2" + Task = "(L1) Ensure 'Configure NetBIOS settings' is set to 2 - 'Enabled: Disable NetBIOS name resolution on public networks' (or 0 - Disable NetBIOS name resolution)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableNetBIOS" ` + | Select-Object -ExpandProperty "EnableNetBIOS" + + if (($regValue -ne 2) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2 or x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.3" + Task = "(L1) Ensure 'Turn off multicast name resolution' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.5.1" + Task = "(L2) Ensure 'Enable Font Providers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableFontProviders" ` + | Select-Object -ExpandProperty "EnableFontProviders" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.1" + Task = "(L1) Ensure 'Enable insecure guest logons' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 A" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnDomain" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 B" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnPublicNet" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 C" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (EnableLLTDIO)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableLLTDIO" ` + | Select-Object -ExpandProperty "EnableLLTDIO" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 D" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitLLTDIOOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitLLTDIOOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 A" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnDomain" ` + | Select-Object -ExpandProperty "AllowRspndrOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 B" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnPublicNet" ` + | Select-Object -ExpandProperty "AllowRspndrOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 C" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (EnableRspndr)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableRspndr" ` + | Select-Object -ExpandProperty "EnableRspndr" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 D" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitRspndrOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitRspndrOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.10.2" + Task = "(L2) Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Peernet" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.2" + Task = "(L1) Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.3" + Task = "(L1) Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 A" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`" and `"Require Integrity`" set for all NETLOGON and SYSVOL shares' (\\*\NETLOGON)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 B" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "RequirePrivacy=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.19.2.1" + Task = "(L2) Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "DisabledComponents" ` + | Select-Object -ExpandProperty "DisabledComponents" + + if (($regValue -ne 255)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 A" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (EnableRegistrars)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "EnableRegistrars" ` + | Select-Object -ExpandProperty "EnableRegistrars" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 B" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableUPnPRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableUPnPRegistrar" ` + | Select-Object -ExpandProperty "DisableUPnPRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 C" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableInBand802DOT11Registrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableInBand802DOT11Registrar" ` + | Select-Object -ExpandProperty "DisableInBand802DOT11Registrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 D" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableFlashConfigRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableFlashConfigRegistrar" ` + | Select-Object -ExpandProperty "DisableFlashConfigRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 E" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableWPDRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableWPDRegistrar" ` + | Select-Object -ExpandProperty "DisableWPDRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.2" + Task = "(L2) Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\UI" ` + -Name "DisableWcnUi" ` + | Select-Object -ExpandProperty "DisableWcnUi" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.1" + Task = "(L1) Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled: 3 = Prevent Wi-Fi when on Ethernet'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fMinimizeConnections" ` + | Select-Object -ExpandProperty "fMinimizeConnections" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.23.2.1" + Task = "(L1) Ensure 'Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config" ` + -Name "AutoConnectAllowedOEM" ` + | Select-Object -ExpandProperty "AutoConnectAllowedOEM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.1" + Task = "(L1) Ensure 'Allow Print Spooler to accept client connections' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "RegisterSpoolerRemoteRpcEndPoint" ` + | Select-Object -ExpandProperty "RegisterSpoolerRemoteRpcEndPoint" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.2" + Task = "(L1) Ensure 'Configure Redirection Guard' is set to 'Enabled: Redirection Guard Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "RedirectionguardPolicy" ` + | Select-Object -ExpandProperty "RedirectionguardPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.3" + Task = "(L1) Ensure 'Configure RPC connection settings: Protocol to use for outgoing RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcUseNamedPipeProtocol" ` + | Select-Object -ExpandProperty "RpcUseNamedPipeProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.4" + Task = "(L1) Ensure 'Configure RPC connection settings: Use authentication for outgoing RPC connections' is set to 'Enabled: Default'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcAuthentication" ` + | Select-Object -ExpandProperty "RpcAuthentication" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.5" + Task = "(L1) Ensure 'Configure RPC listener settings: Protocols to allow for incoming RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcProtocols" ` + | Select-Object -ExpandProperty "RpcProtocols" + + if (($regValue -ne 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.6" + Task = "(L1) Ensure 'Configure RPC listener settings: Authentication protocol to use for incoming RPC connections:' is set to 'Enabled: Negotiate' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "ForceKerberosForRpc" ` + | Select-Object -ExpandProperty "ForceKerberosForRpc" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0 or x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.7" + Task = "(L1) Ensure 'Configure RPC over TCP port' is set to 'Enabled: 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcTcpPort" ` + | Select-Object -ExpandProperty "RpcTcpPort" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.8" + Task = "(L1) Ensure 'Limits print driver installation to Administrators' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "RestrictDriverInstallationToAdministrators" ` + | Select-Object -ExpandProperty "RestrictDriverInstallationToAdministrators" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.9" + Task = "(L1) Ensure 'Manage processing of Queue-specific files' is set to 'Enabled: Limit Queue-specific files to Color profiles'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "CopyFilesPolicy" ` + | Select-Object -ExpandProperty "CopyFilesPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.10" + Task = "(L1) Ensure 'Point and Print Restrictions: When installing drivers for a new connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "NoWarningNoElevationOnInstall" ` + | Select-Object -ExpandProperty "NoWarningNoElevationOnInstall" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.11" + Task = "(L1) Ensure 'Point and Print Restrictions: When updating drivers for an existing connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "UpdatePromptSettings" ` + | Select-Object -ExpandProperty "UpdatePromptSettings" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.1.1" + Task = "(L2) Ensure 'Turn off notifications network usage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.3.1" + Task = "(L1) Ensure 'Include command line in process creation events' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.1" + Task = "(L1) Ensure 'Encryption Oracle Remediation' is set to 'Enabled: Force Updated Clients'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.2" + Task = "(L1) Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.1" + Task = "(L1) Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.2" + Task = "(L1) Ensure 'Turn On Virtualization Based Security: Select Platform Security Level' is set to 'Secure Boot' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if (($regValue -ne 3) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 3 or x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.3" + Task = "(L1) Ensure 'Turn On Virtualization Based Security: Virtualization Based Protection of Code Integrity' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.4" + Task = "(L1) Ensure 'Turn On Virtualization Based Security: Require UEFI Memory Attributes Table' is set to 'True (checked)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HVCIMATRequired" ` + | Select-Object -ExpandProperty "HVCIMATRequired" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.5" + Task = "(L1) Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.6" + Task = "(L1) Ensure 'Turn On Virtualization Based Security: Secure Launch Configuration' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureSystemGuardLaunch" ` + | Select-Object -ExpandProperty "ConfigureSystemGuardLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.7" + Task = "(L1) Ensure 'Turn On Virtualization Based Security: Kernel-mode Hardware-enforced Stack Protection' is set to 'Enabled: Enabled in enforcement mode'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureKernelShadowStacksLaunch" ` + | Select-Object -ExpandProperty "ConfigureKernelShadowStacksLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.1" + Task = "(BL) Ensure 'Prevent installation of devices that match any of these device IDs' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceIDs" ` + | Select-Object -ExpandProperty "DenyDeviceIDs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.2" + Task = "(BL) Ensure 'Prevent installation of devices that match any of these device IDs: Prevent installation of devices that match any of these device IDs' is set to 'PCI\CC_0C0A'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceIDs" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "PCI\CC_0C0A") { + return @{ + Message = "Registry value is '$regValue'. Expected: PCI\CC_0C0A" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.3" + Task = "(BL) Ensure 'Prevent installation of devices that match any of these device IDs: Also apply to matching devices that are already installed.' is set to 'True' (checked)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceIDsRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceIDsRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.4" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClasses" ` + | Select-Object -ExpandProperty "DenyDeviceClasses" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.5 A" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the SBP2 Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "1" ` + | Select-Object -ExpandProperty "1" + + if ($regValue -ne "{d48179be-ec20-11d1-b6b8-00c04fa372a7}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {d48179be-ec20-11d1-b6b8-00c04fa372a7}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.5 B" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the IEC-61883 Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "2" ` + | Select-Object -ExpandProperty "2" + + if ($regValue -ne "{7ebefbc0-3200-11d2-b4c2-00a0C9697d07}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {7ebefbc0-3200-11d2-b4c2-00a0C9697d07}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.5 C" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 devices that support the AVC Protocol Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "3" ` + | Select-Object -ExpandProperty "3" + + if ($regValue -ne "{c06ff265-ae09-48f0-812c-16753d7cba83}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {c06ff265-ae09-48f0-812c-16753d7cba83}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.5 D" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Prevent installation of devices using drivers for these device setup' is set to 'IEEE 1394 device setup classes' [IEEE 1394 Host Bus Controller Class]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions\DenyDeviceClasses" ` + -Name "4" ` + | Select-Object -ExpandProperty "4" + + if ($regValue -ne "{6bdd1fc1-810f-11d0-bec7-08002be2092f}") { + return @{ + Message = "Registry value is '$regValue'. Expected: {6bdd1fc1-810f-11d0-bec7-08002be2092f}" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.1.6" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Also apply to matching devices that are already installed.' is set to 'True' (checked)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClassesRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceClassesRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.2" + Task = "(L1) Ensure 'Prevent device metadata retrieval from the Internet' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" ` + -Name "PreventDeviceMetadataFromNetwork" ` + | Select-Object -ExpandProperty "PreventDeviceMetadataFromNetwork" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.13.1" + Task = "(L1) Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.2" + Task = "(L1) Ensure 'Continue experiences on this device' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableCdp" ` + | Select-Object -ExpandProperty "EnableCdp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.1" + Task = "(L2) Ensure 'Turn off access to the Store' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoUseStoreOpenWith" ` + | Select-Object -ExpandProperty "NoUseStoreOpenWith" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.2" + Task = "(L1) Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.3" + Task = "(L2) Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TabletPC" ` + -Name "PreventHandwritingDataSharing" ` + | Select-Object -ExpandProperty "PreventHandwritingDataSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.4" + Task = "(L2) Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HandwritingErrorReports" ` + -Name "PreventHandwritingErrorReports" ` + | Select-Object -ExpandProperty "PreventHandwritingErrorReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.5" + Task = "(L2) Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Internet Connection Wizard" ` + -Name "ExitOnMSICW" ` + | Select-Object -ExpandProperty "ExitOnMSICW" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.6" + Task = "(L1) Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.7" + Task = "(L2) Ensure 'Turn off printing over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.8" + Task = "(L2) Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Registration Wizard Control" ` + -Name "NoRegistration" ` + | Select-Object -ExpandProperty "NoRegistration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.9" + Task = "(L2) Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SearchCompanion" ` + -Name "DisableContentFileUpdates" ` + | Select-Object -ExpandProperty "DisableContentFileUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.10" + Task = "(L2) Ensure 'Turn off the `"Order Prints`" picture task' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoOnlinePrintsWizard" ` + | Select-Object -ExpandProperty "NoOnlinePrintsWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.11" + Task = "(L2) Ensure 'Turn off the `"Publish to Web`" task for files and folders' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoPublishingWizard" ` + | Select-Object -ExpandProperty "NoPublishingWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.12" + Task = "(L2) Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Messenger\Client" ` + -Name "CEIP" ` + | Select-Object -ExpandProperty "CEIP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13" + Task = "(L2) Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SQMClient\Windows" ` + -Name "CEIPEnable" ` + | Select-Object -ExpandProperty "CEIPEnable" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.14 A" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (Disabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.14 B" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (DoReport)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\PCHealth\ErrorReporting" ` + -Name "DoReport" ` + | Select-Object -ExpandProperty "DoReport" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 A" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitBehavior)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitBehavior" ` + | Select-Object -ExpandProperty "DevicePKInitBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 B" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitEnabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitEnabled" ` + | Select-Object -ExpandProperty "DevicePKInitEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.1" + Task = "(BL) Ensure 'Enumeration policy for external devices incompatible with Kernel DMA Protection' is set to 'Enabled: Block All'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.1" + Task = "(L1) Ensure 'Allow Custom SSPs and APs to be loaded into LSASS' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowCustomSSPsAPs" ` + | Select-Object -ExpandProperty "AllowCustomSSPsAPs" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.2" + Task = "(L1) Ensure 'Configures LSASS to run as a protected process' is set to 'Enabled: Enabled with UEFI Lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RunAsPPL" ` + | Select-Object -ExpandProperty "RunAsPPL" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.1" + Task = "(L2) Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Control Panel\International" ` + -Name "BlockUserInputMethodsForSignIn" ` + | Select-Object -ExpandProperty "BlockUserInputMethodsForSignIn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.1" + Task = "(L1) Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockUserFromShowingAccountDetailsOnSignin" ` + | Select-Object -ExpandProperty "BlockUserFromShowingAccountDetailsOnSignin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.2" + Task = "(L1) Ensure 'Do not display network selection UI' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.3" + Task = "(L1) Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.4" + Task = "(L1) Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.30.1" + Task = "(L2) Ensure 'Allow Clipboard synchronization across devices' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowCrossDeviceClipboard" ` + | Select-Object -ExpandProperty "AllowCrossDeviceClipboard" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.30.2" + Task = "(L2) Ensure 'Allow upload of User Activities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "UploadUserActivities" ` + | Select-Object -ExpandProperty "UploadUserActivities" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.1" + Task = "(L1) Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.2" + Task = "(L1) Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.3" + Task = "(BL) Ensure 'Allow standby states (S1-S3) when sleeping (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.4" + Task = "(BL) Ensure 'Allow standby states (S1-S3) when sleeping (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.5" + Task = "(L1) Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.6" + Task = "(L1) Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.34.1" + Task = "(L1) Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.34.2" + Task = "(L1) Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.1" + Task = "(L1) Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "EnableAuthEpResolution" ` + | Select-Object -ExpandProperty "EnableAuthEpResolution" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.2" + Task = "(L1) Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.46.5.1" + Task = "(L2) Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.46.11.1" + Task = "(L2) Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d}" ` + -Name "ScenarioExecutionEnabled" ` + | Select-Object -ExpandProperty "ScenarioExecutionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.48.1" + Task = "(L2) Ensure 'Turn off the advertising ID' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" ` + -Name "DisabledByGroupPolicy" ` + | Select-Object -ExpandProperty "DisabledByGroupPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.50.1.1" + Task = "(L1) Ensure 'Enable Windows NTP Client' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.3.1" + Task = "(L2) Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager" ` + -Name "AllowSharedLocalAppData" ` + | Select-Object -ExpandProperty "AllowSharedLocalAppData" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.3.2" + Task = "(L1) Ensure 'Prevent non-admin users from installing packaged Windows apps' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Appx" ` + -Name "BlockNonAdminUserInstall" ` + | Select-Object -ExpandProperty "BlockNonAdminUserInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.4.1" + Task = "(L1) Ensure 'Let Windows apps activate with voice while the system is locked' is set to 'Enabled: Force Deny'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy" ` + -Name "LetAppsActivateWithVoiceAboveLock" ` + | Select-Object -ExpandProperty "LetAppsActivateWithVoiceAboveLock" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.5.1" + Task = "(L1) Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.5.2" + Task = "(L2) Ensure 'Block launching Universal Windows apps with Windows Runtime API access from hosted content.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "BlockHostedAppAccessWinRT" ` + | Select-Object -ExpandProperty "BlockHostedAppAccessWinRT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.1" + Task = "(L1) Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.2" + Task = "(L1) Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.3" + Task = "(L1) Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.8.1.1" + Task = "(L1) Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.1" + Task = "(BL) Ensure 'Allow access to BitLocker-protected fixed data drives from earlier versions of Windows' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVDiscoveryVolumeType" ` + | Select-Object -ExpandProperty "FDVDiscoveryVolumeType" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: This value should be empty." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.2" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecovery" ` + | Select-Object -ExpandProperty "FDVRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Allow data recovery agent' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVManageDRA" ` + | Select-Object -ExpandProperty "FDVManageDRA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Recovery Password' is set to 'Enabled: Allow 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecoveryPassword" ` + | Select-Object -ExpandProperty "FDVRecoveryPassword" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Recovery Key' is set to 'Enabled: Allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecoveryKey" ` + | Select-Object -ExpandProperty "FDVRecoveryKey" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVHideRecoveryPage" ` + | Select-Object -ExpandProperty "FDVHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Save BitLocker recovery information to AD DS for fixed data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "FDVActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Configure storage of BitLocker recovery information to AD DS' is set to 'Enabled: Backup recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "FDVActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for fixed data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "FDVRequireActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.10" + Task = "(BL) Ensure 'Configure use of hardware-based encryption for fixed data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVHardwareEncryption" ` + | Select-Object -ExpandProperty "FDVHardwareEncryption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.11" + Task = "(BL) Ensure 'Configure use of passwords for fixed data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVPassphrase" ` + | Select-Object -ExpandProperty "FDVPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.12" + Task = "(BL) Ensure 'Configure use of smart cards on fixed data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVAllowUserCert" ` + | Select-Object -ExpandProperty "FDVAllowUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.13" + Task = "(BL) Ensure 'Configure use of smart cards on fixed data drives: Require use of smart cards on fixed data drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVEnforceUserCert" ` + | Select-Object -ExpandProperty "FDVEnforceUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.1" + Task = "(BL) Ensure 'Allow enhanced PINs for startup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "UseEnhancedPin" ` + | Select-Object -ExpandProperty "UseEnhancedPin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.2" + Task = "(BL) Ensure 'Allow Secure Boot for integrity validation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "OSAllowSecureBootForIntegrity" ` + | Select-Object -ExpandProperty "OSAllowSecureBootForIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecovery" ` + | Select-Object -ExpandProperty "OSRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Allow data recovery agent' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSManageDRA" ` + | Select-Object -ExpandProperty "OSManageDRA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Recovery Password' is set to 'Enabled: Require 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecoveryPassword" ` + | Select-Object -ExpandProperty "OSRecoveryPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Recovery Key' is set to 'Enabled: Do not allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecoveryKey" ` + | Select-Object -ExpandProperty "OSRecoveryKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSHideRecoveryPage" ` + | Select-Object -ExpandProperty "OSHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Save BitLocker recovery information to AD DS for operating system drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "OSActiveDirectoryBackup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Configure storage of BitLocker recovery information to AD DS:' is set to 'Enabled: Store recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "OSActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.10" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for operating system drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "OSRequireActiveDirectoryBackup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.11" + Task = "(BL) Ensure 'Configure use of hardware-based encryption for operating system drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSHardwareEncryption" ` + | Select-Object -ExpandProperty "OSHardwareEncryption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.12" + Task = "(BL) Ensure 'Configure use of passwords for operating system drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "OSPassphrase" ` + | Select-Object -ExpandProperty "OSPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.13" + Task = "(BL) Ensure 'Require additional authentication at startup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseAdvancedStartup" ` + | Select-Object -ExpandProperty "UseAdvancedStartup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.2.14" + Task = "(BL) Ensure 'Require additional authentication at startup: Allow BitLocker without a compatible TPM' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "EnableBDEWithNoTPM" ` + | Select-Object -ExpandProperty "EnableBDEWithNoTPM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.1" + Task = "(BL) Ensure 'Allow access to BitLocker-protected removable data drives from earlier versions of Windows' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVDiscoveryVolumeType" ` + | Select-Object -ExpandProperty "RDVDiscoveryVolumeType" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.2" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecovery" ` + | Select-Object -ExpandProperty "RDVRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Allow data recovery agent' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVManageDRA" ` + | Select-Object -ExpandProperty "RDVManageDRA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Recovery Password' is set to 'Enabled: Do not allow 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecoveryPassword" ` + | Select-Object -ExpandProperty "RDVRecoveryPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Recovery Key' is set to 'Enabled: Do not allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecoveryKey" ` + | Select-Object -ExpandProperty "RDVRecoveryKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVHideRecoveryPage" ` + | Select-Object -ExpandProperty "RDVHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Save BitLocker recovery information to AD DS for removable data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "RDVActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Configure storage of BitLocker recovery information to AD DS:' is set to 'Enabled: Backup recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "RDVActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for removable data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "RDVRequireActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.10" + Task = "(BL) Ensure 'Configure use of hardware-based encryption for removable data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVHardwareEncryption" ` + | Select-Object -ExpandProperty "RDVHardwareEncryption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.11" + Task = "(BL) Ensure 'Configure use of passwords for removable data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVPassphrase" ` + | Select-Object -ExpandProperty "RDVPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.12" + Task = "(BL) Ensure 'Configure use of smart cards on removable data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVAllowUserCert" ` + | Select-Object -ExpandProperty "RDVAllowUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.13" + Task = "(BL) Ensure 'Configure use of smart cards on removable data drives: Require use of smart cards on removable data drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVEnforceUserCert" ` + | Select-Object -ExpandProperty "RDVEnforceUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.14" + Task = "(BL) Ensure 'Deny write access to removable drives not protected by BitLocker' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\Microsoft\FVE" ` + -Name "RDVDenyWriteAccess" ` + | Select-Object -ExpandProperty "RDVDenyWriteAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.3.15" + Task = "(BL) Ensure 'Deny write access to removable drives not protected by BitLocker: Do not allow write access to devices configured in another organization' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVDenyCrossOrg" ` + | Select-Object -ExpandProperty "RDVDenyCrossOrg" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.4" + Task = "(BL) Ensure 'Disable new DMA devices when this computer is locked' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "DisableExternalDMAUnderLock" ` + | Select-Object -ExpandProperty "DisableExternalDMAUnderLock" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1" + Task = "(L2) Ensure 'Allow Use of Camera' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera" ` + -Name "AllowCamera" ` + | Select-Object -ExpandProperty "AllowCamera" + + if ($regValue -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam" ` + -Name "Value" ` + | Select-Object -ExpandProperty "Value" + + if ($regValue -match "Deny") { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Camera is not deactivated." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "18.10.12.1" + Task = "(L1) Ensure 'Turn off cloud consumer account state content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableConsumerAccountStateContent" ` + | Select-Object -ExpandProperty "DisableConsumerAccountStateContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.12.2" + Task = "(L2) Ensure 'Turn off cloud optimized content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableCloudOptimizedContent" ` + | Select-Object -ExpandProperty "DisableCloudOptimizedContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.12.3" + Task = "(L1) Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.13.1" + Task = "(L1) Ensure 'Require pin for pairing' is set to 'Enabled: First Time' OR 'Enabled: Always'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect" ` + -Name "RequirePinForPairing" ` + | Select-Object -ExpandProperty "RequirePinForPairing" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.1" + Task = "(L1) Ensure 'Do not display the password reveal button' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.2" + Task = "(L1) Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.3" + Task = "(L1) Ensure 'Prevent the use of security questions for local accounts' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "NoLocalPasswordResetQuestions" ` + | Select-Object -ExpandProperty "NoLocalPasswordResetQuestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.1" + Task = "(L1) Ensure 'Allow Diagnostic Data' is set to '0 - Enabled: Diagnostic data off (not recommended)' or '1 - Enabled: Send required diagnostic data'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0 or x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.2" + Task = "(L2) Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableEnterpriseAuthProxy" ` + | Select-Object -ExpandProperty "DisableEnterpriseAuthProxy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.3" + Task = "(L1) Ensure 'Disable OneSettings Downloads' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableOneSettingsDownloads" ` + | Select-Object -ExpandProperty "DisableOneSettingsDownloads" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.4" + Task = "(L1) Ensure 'Do not show feedback notifications' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DoNotShowFeedbackNotifications" ` + | Select-Object -ExpandProperty "DoNotShowFeedbackNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.5" + Task = "(L1) Ensure 'Enable OneSettings Auditing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "EnableOneSettingsAuditing" ` + | Select-Object -ExpandProperty "EnableOneSettingsAuditing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.6" + Task = "(L1) Ensure 'Limit Diagnostic Log Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDiagnosticLogCollection" ` + | Select-Object -ExpandProperty "LimitDiagnosticLogCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.7" + Task = "(L1) Ensure 'Limit Dump Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDumpCollection" ` + | Select-Object -ExpandProperty "LimitDumpCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.8" + Task = "(L1) Ensure 'Toggle user control over Insider builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" ` + -Name "AllowBuildPreview" ` + | Select-Object -ExpandProperty "AllowBuildPreview" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.1" + Task = "(L1) Ensure 'Download Mode' is NOT set to 'Enabled: Internet'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeliveryOptimization" ` + -Name "DODownloadMode" ` + | Select-Object -ExpandProperty "DODownloadMode" + + if (($regValue -eq 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x != 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.1" + Task = "(L1) Ensure 'Enable App Installer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableAppInstaller" ` + | Select-Object -ExpandProperty "EnableAppInstaller" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.2" + Task = "(L1) Ensure 'Enable App Installer Experimental Features' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableExperimentalFeatures" ` + | Select-Object -ExpandProperty "EnableExperimentalFeatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.3" + Task = "(L1) Ensure 'Enable App Installer Hash Override' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableHashOverride" ` + | Select-Object -ExpandProperty "EnableHashOverride" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.4" + Task = "(L1) Ensure 'Enable App Installer ms-appinstaller protocol' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableMSAppInstallerProtocol" ` + | Select-Object -ExpandProperty "EnableMSAppInstallerProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.1.1" + Task = "(L1) Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.1.2" + Task = "(L1) Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.2.1" + Task = "(L1) Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.2.2" + Task = "(L1) Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 196608)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.3.1" + Task = "(L1) Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.3.2" + Task = "(L1) Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.4.1" + Task = "(L1) Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.4.2" + Task = "(L1) Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.2" + Task = "(L1) Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.3" + Task = "(L2) Ensure 'Turn off files from Office.com in Quick access view' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "DisableGraphRecentItems" ` + | Select-Object -ExpandProperty "DisableGraphRecentItems" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.4" + Task = "(L1) Ensure 'Turn off heap termination on corruption' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.5" + Task = "(L1) Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.33.1" + Task = "(L1) Ensure 'Prevent the computer from joining a homegroup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HomeGroup" ` + -Name "DisableHomeGroup" ` + | Select-Object -ExpandProperty "DisableHomeGroup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.37.1" + Task = "(L2) Ensure 'Turn off location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.41.1" + Task = "(L2) Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging" ` + -Name "AllowMessageSync" ` + | Select-Object -ExpandProperty "AllowMessageSync" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.1" + Task = "(L1) Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount" ` + -Name "DisableUserAuth" ` + | Select-Object -ExpandProperty "DisableUserAuth" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.5.1" + Task = "(L1) Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.5.2" + Task = "(L2) Ensure 'Join Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.1" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 A" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office communication application from creating child processes'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 B" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating executable content'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 D" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block execution of potentially obfuscated scripts'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 E" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from injecting code into other processes'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 F" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Adobe Reader from creating child processes'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 G" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Win32 API calls from Office macro'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 H" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block credential stealing from the Windows local security authority subsystem (lsass.exe)'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 I" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block untrusted and unsigned processes that run from USB'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 J" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block executable content from email client and webmail'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 K" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block JavaScript or VBScript from launching downloaded executable content'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 L" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating child processes'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 M" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block persistence through WMI event subscription'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.3.1" + Task = "(L1) Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.7.1" + Task = "(L2) Ensure 'Enable file hash computation feature' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\MpEngine" ` + -Name "EnableFileHashComputation" ` + | Select-Object -ExpandProperty "EnableFileHashComputation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.1" + Task = "(L1) Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.2" + Task = "(L1) Ensure 'Turn off real-time protection' is set to 'Disabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.3" + Task = "(L1) Ensure 'Turn on behavior monitoring' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.4" + Task = "(L1) Ensure 'Turn on script scanning' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableScriptScanning" ` + | Select-Object -ExpandProperty "DisableScriptScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.12.1" + Task = "(L2) Ensure 'Configure Watson events' is set to 'Disabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" ` + -Name "DisableGenericReports" ` + | Select-Object -ExpandProperty "DisableGenericReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.1" + Task = "(L1) Ensure 'Scan removable drives' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.2" + Task = "(L1) Ensure 'Turn on e-mail scanning' is set to 'Enabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.16" + Task = "(L1) Ensure 'Configure detection for potentially unwanted applications' is set to 'Enabled: Block'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.17" + Task = "(L1) Ensure 'Turn off Microsoft Defender AntiVirus' is set to 'Disabled'" + Test = { + try { + if($avstatus){ + + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "DisableAntiSpyware" ` + | Select-Object -ExpandProperty "DisableAntiSpyware" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.1" + Task = "(L1) Ensure 'Allow auditing events in Microsoft Defender Application Guard' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AuditApplicationGuard" ` + | Select-Object -ExpandProperty "AuditApplicationGuard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.2" + Task = "(L1) Ensure 'Allow camera and microphone access in Microsoft Defender Application Guard' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowCameraMicrophoneRedirection" ` + | Select-Object -ExpandProperty "AllowCameraMicrophoneRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.3" + Task = "(L1) Ensure 'Allow data persistence for Microsoft Defender Application Guard' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowPersistence" ` + | Select-Object -ExpandProperty "AllowPersistence" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.4" + Task = "(L1) Ensure 'Allow files to download and save to the host operating system from Microsoft Defender Application Guard' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "SaveFilesToHost" ` + | Select-Object -ExpandProperty "SaveFilesToHost" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.5" + Task = "(L1) Ensure 'Configure Microsoft Defender Application Guard clipboard settings: Clipboard behavior setting' is set to 'Enabled: Enable clipboard operation from an isolated session to the host'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AppHVSIClipboardSettings" ` + | Select-Object -ExpandProperty "AppHVSIClipboardSettings" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.44.6" + Task = "(L1) Ensure 'Turn on Microsoft Defender Application Guard in Managed Mode' is set to 'Enabled: 1'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\AppHVSI" ` + -Name "AllowAppHVSI_ProviderSet" ` + | Select-Object -ExpandProperty "AllowAppHVSI_ProviderSet" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + "
Warning: Defender Application Guard is deprecated. More info." + Status = "False" + } + } + + return @{ + Message = "Compliant" + "
Warning: Defender Application Guard is deprecated. More info." + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.50.1" + Task = "(L2) Ensure 'Enable news and interests on the taskbar' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Feeds" ` + -Name "EnableFeeds" ` + | Select-Object -ExpandProperty "EnableFeeds" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.51.1" + Task = "(L1) Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.1" + Task = "(L2) Ensure 'Turn off Push To Install service' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall" ` + -Name "DisablePushToInstall" ` + | Select-Object -ExpandProperty "DisablePushToInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.2.2" + Task = "(L2) Ensure 'Disable Cloud Clipboard integration for server-to-client data transfer' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\Client" ` + -Name "DisableCloudClipboardIntegration" ` + | Select-Object -ExpandProperty "DisableCloudClipboardIntegration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.2.3" + Task = "(L1) Ensure 'Do not allow passwords to be saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.2.1" + Task = "(L2) Ensure 'Allow users to connect remotely by using Remote Desktop Services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDenyTSConnections" ` + | Select-Object -ExpandProperty "fDenyTSConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.1" + Task = "(L2) Ensure 'Allow UI Automation redirection' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "EnableUiaRedirection" ` + | Select-Object -ExpandProperty "EnableUiaRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.2" + Task = "(L2) Ensure 'Do not allow COM port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCcm" ` + | Select-Object -ExpandProperty "fDisableCcm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.3" + Task = "(L1) Ensure 'Do not allow drive redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.4" + Task = "(L2) Ensure 'Do not allow location redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLocationRedir" ` + | Select-Object -ExpandProperty "fDisableLocationRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.5" + Task = "(L2) Ensure 'Do not allow LPT port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLPT" ` + | Select-Object -ExpandProperty "fDisableLPT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.6" + Task = "(L2) Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisablePNPRedir" ` + | Select-Object -ExpandProperty "fDisablePNPRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.7" + Task = "(L2) Ensure 'Do not allow WebAuthn redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableWebAuthn" ` + | Select-Object -ExpandProperty "fDisableWebAuthn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.1" + Task = "(L1) Ensure 'Always prompt for password upon connection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.2" + Task = "(L1) Ensure 'Require secure RPC communication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.3" + Task = "(L1) Ensure 'Require use of specific security layer for remote (RDP) connections' is set to 'Enabled: SSL'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SecurityLayer" ` + | Select-Object -ExpandProperty "SecurityLayer" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.4" + Task = "(L1) Ensure 'Require user authentication for remote connections by using Network Level Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "UserAuthentication" ` + | Select-Object -ExpandProperty "UserAuthentication" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.5" + Task = "(L1) Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.10.1" + Task = "(L2) Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less, but not Never (0)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxIdleTime" ` + | Select-Object -ExpandProperty "MaxIdleTime" + + if (($regValue -gt 900000 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900000 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.10.2" + Task = "(L2) Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxDisconnectionTime" ` + | Select-Object -ExpandProperty "MaxDisconnectionTime" + + if ($regValue -ne 60000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 60000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.11.1" + Task = "(L1) Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.1" + Task = "(L1) Ensure 'Prevent downloading of enclosures' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.2" + Task = "(L2) Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCloudSearch" ` + | Select-Object -ExpandProperty "AllowCloudSearch" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.3" + Task = "(L1) Ensure 'Allow Cortana' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCortana" ` + | Select-Object -ExpandProperty "AllowCortana" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.4" + Task = "(L1) Ensure 'Allow Cortana above lock screen' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCortanaAboveLock" ` + | Select-Object -ExpandProperty "AllowCortanaAboveLock" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.5" + Task = "(L1) Ensure 'Allow indexing of encrypted files' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.6" + Task = "(L1) Ensure 'Allow search and Cortana to use location' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowSearchToUseLocation" ` + | Select-Object -ExpandProperty "AllowSearchToUseLocation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.7" + Task = "(L2) Ensure 'Allow search highlights' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "EnableDynamicContentInWSB" ` + | Select-Object -ExpandProperty "EnableDynamicContentInWSB" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.63.1" + Task = "(L2) Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" ` + -Name "NoGenTicket" ` + | Select-Object -ExpandProperty "NoGenTicket" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.1" + Task = "(L2) Ensure 'Disable all apps from Microsoft Store' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "DisableStoreApps" ` + | Select-Object -ExpandProperty "DisableStoreApps" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.2" + Task = "(L1) Ensure 'Only display the private store within the Microsoft Store' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "RequirePrivateStoreOnly" ` + | Select-Object -ExpandProperty "RequirePrivateStoreOnly" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.3" + Task = "(L1) Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "AutoDownload" ` + | Select-Object -ExpandProperty "AutoDownload" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.4" + Task = "(L1) Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "DisableOSUpgrade" ` + | Select-Object -ExpandProperty "DisableOSUpgrade" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.66.5" + Task = "(L2) Ensure 'Turn off the Store application' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "RemoveWindowsStore" ` + | Select-Object -ExpandProperty "RemoveWindowsStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.72.1" + Task = "(L1) Ensure 'Allow widgets' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Dsh" ` + -Name "AllowNewsAndInterests" ` + | Select-Object -ExpandProperty "AllowNewsAndInterests" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.1.1" + Task = "(L1) Ensure 'Notify Malicious' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "NotifyMalicious" ` + | Select-Object -ExpandProperty "NotifyMalicious" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.1.2" + Task = "(L1) Ensure 'Notify Password Reuse' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "NotifyPasswordReuse" ` + | Select-Object -ExpandProperty "NotifyPasswordReuse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.1.3" + Task = "(L1) Ensure 'Notify Unsafe App' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "NotifyUnsafeApp" ` + | Select-Object -ExpandProperty "NotifyUnsafeApp" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.1.4" + Task = "(L1) Ensure 'Service Enabled' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WTDS\Components" ` + -Name "ServiceEnabled" ` + | Select-Object -ExpandProperty "ServiceEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.2.1 A" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (EnableSmartScreen)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.2.1 B" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (ShellSmartScreenLevel)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.3.1" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.3.2" + Task = "(L1) Ensure 'Prevent bypassing Windows Defender SmartScreen prompts for sites' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.78.1" + Task = "(L1) Ensure 'Enables or disables Windows Game Recording and Broadcasting' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR" ` + -Name "AllowGameDVR" ` + | Select-Object -ExpandProperty "AllowGameDVR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.79.1" + Task = "(L1) Ensure 'Enable ESS with Supported Peripherals' is set to 'Enabled: 1'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Policies\PassportForWork\Biometrics" ` + -Name "EnableESSwithSupportedPeripherals" ` + | Select-Object -ExpandProperty "EnableESSwithSupportedPeripherals" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.1" + Task = "(L2) Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowSuggestedAppsInWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowSuggestedAppsInWindowsInkWorkspace" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.2" + Task = "(L1) Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Enabled: Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if (($regValue -ne 1) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.1" + Task = "(L1) Ensure 'Allow user control over installs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.2" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.3" + Task = "(L2) Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.82.1" + Task = "(L1) Ensure 'Enable MPR notifications for the system' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableMPR" ` + | Select-Object -ExpandProperty "EnableMPR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.82.2" + Task = "(L1) Ensure 'Sign-in and lock last interactive user automatically after a restart' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.87.1" + Task = "(L1) Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.87.2" + Task = "(L1) Ensure 'Turn on PowerShell Transcription' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" ` + -Name "EnableTranscripting" ` + | Select-Object -ExpandProperty "EnableTranscripting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.2" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.3" + Task = "(L1) Ensure 'Disallow Digest authentication' is set to 'Enabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.2" + Task = "(L2) Ensure 'Allow remote server management through WinRM' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowAutoConfig" ` + | Select-Object -ExpandProperty "AllowAutoConfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.3" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.4" + Task = "(L1) Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.90.1" + Task = "(L2) Ensure 'Allow Remote Shell Access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service\WinRS" ` + -Name "AllowRemoteShellAccess" ` + | Select-Object -ExpandProperty "AllowRemoteShellAccess" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.91.1" + Task = "(L1) Ensure 'Allow clipboard sharing with Windows Sandbox' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Sandbox" ` + -Name "AllowClipboardRedirection" ` + | Select-Object -ExpandProperty "AllowClipboardRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.91.2" + Task = "(L1) Ensure 'Allow networking in Windows Sandbox' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Sandbox" ` + -Name "AllowNetworking" ` + | Select-Object -ExpandProperty "AllowNetworking" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.1" + Task = "(L1) Ensure 'Prevent users from modifying settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection" ` + -Name "DisallowExploitProtectionOverride" ` + | Select-Object -ExpandProperty "DisallowExploitProtectionOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.1.1" + Task = "(L1) Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.1" + Task = "(L1) Ensure 'Configure Automatic Updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.2" + Task = "(L1) Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.3" + Task = "(L1) Ensure 'Remove access to `"Pause updates`" feature' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "SetDisablePauseUXAccess" ` + | Select-Object -ExpandProperty "SetDisablePauseUXAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.1" + Task = "(L1) Ensure 'Manage preview builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "ManagePreviewBuildsPolicyValue" ` + | Select-Object -ExpandProperty "ManagePreviewBuildsPolicyValue" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.2 A" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdates" ` + | Select-Object -ExpandProperty "DeferFeatureUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.2 B" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferFeatureUpdatesPeriodInDays" + + if (($regValue -lt 180 -or $regValue -gt 365)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 180 and x <= 365" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.2 C" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: Semi-Annual Channel, 180 or more days' (BranchReadinessLevel)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "BranchReadinessLevel" ` + | Select-Object -ExpandProperty "BranchReadinessLevel" + + if (($regValue -ne 32)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 32" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.3 A" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdates" ` + | Select-Object -ExpandProperty "DeferQualityUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.3 B" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferQualityUpdatesPeriodInDays" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.1.3.1" + Task = "(L1) Ensure 'Enable screen saver' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaveActive" ` + | Select-Object -ExpandProperty "ScreenSaveActive" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.1.3.2" + Task = "(L1) Ensure 'Password protect the screen saver' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaverIsSecure" ` + | Select-Object -ExpandProperty "ScreenSaverIsSecure" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#SecurityOptions.ps1 new file mode 100644 index 0000000..55176b4 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#SecurityOptions.ps1 @@ -0,0 +1,130 @@ +[AuditTest] @{ + Id = "2.3.1.2" + Task = "(L1) Ensure 'Accounts: Guest account status' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.4" + Task = "(L1) Configure 'Accounts: Rename administrator account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?!.*\bAdministrator\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.5" + Task = "(L1) Configure 'Accounts: Rename guest account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.1" + Task = "(L1) Ensure 'Network access: Allow anonymous SID/Name translation' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.6" + Task = "(L1) Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["ForceLogoffWhenHourExpire"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 1) { + return @{ + Message = "'ForceLogoffWhenHourExpire' currently set to: $setOption. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#UserRights.ps1 new file mode 100644 index 0000000..5e3fb5c --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 11-Stand-alone-CIS-2.0.0#UserRights.ps1 @@ -0,0 +1,1311 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "2.2.1" + Task = "(L1) Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Remote Desktop Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.3" + Task = "(L1) Ensure 'Act as part of the operating system' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.4" + Task = "(L1) Ensure 'Adjust memory quotas for a process' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseQuotaPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeIncreaseQuotaPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.5" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.6" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators, Remote Desktop Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.7" + Task = "(L1) Ensure 'Back up files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.8" + Task = "(L1) Ensure 'Change the system time' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemtimePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeSystemtimePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.9" + Task = "(L1) Ensure 'Change the time zone' is set to 'Administrators, LOCAL SERVICE, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTimeZonePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeTimeZonePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.10" + Task = "(L1) Ensure 'Create a pagefile' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.11" + Task = "(L1) Ensure 'Create a token object' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.12" + Task = "(L1) Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.13" + Task = "(L1) Ensure 'Create permanent shared objects' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if($hyperVStatus -ne "Enabled"){ + [AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Configure 'Create symbolic links' [Hyper-V-Feature NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else{ + [AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Configure 'Create symbolic links' [Hyper-V-Feature installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.15" + Task = "(L1) Ensure 'Debug programs' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.16" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.17" + Task = "(L1) Ensure 'Deny log on as a batch job' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.18" + Task = "(L1) Ensure 'Deny log on as a service' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyServiceLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Deny log on locally' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.20" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.21" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @() | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.22" + Task = "(L1) Ensure 'Force shutdown from a remote system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.23" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.24" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + "S-1-5-20" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.25" + Task = "(L1) Ensure 'Increase scheduling priority' is set to 'Administrators, Window Manager\Window Manager Group'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseBasePriorityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-90-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeIncreaseBasePriorityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.26" + Task = "(L1) Ensure 'Load and unload device drivers' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.27" + Task = "(L1) Ensure 'Lock pages in memory' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.28" + Task = "(L2) Ensure 'Log on as a batch job' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeBatchLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if($hyperVStatus -ne "Enabled"){ + [AuditTest] @{ + Id = "2.2.29" + Task = "(L2) Configure 'Log on as a service' [Hyper-V-Feature NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeServiceLogonRight"] + $identityAccounts = @() | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeServiceLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else{ + [AuditTest] @{ + Id = "2.2.29" + Task = "(L2) Configure 'Log on as a service' [Hyper-V-Feature installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeServiceLogonRight"] + $identityAccounts = @( + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeServiceLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.30" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.31" + Task = "(L1) Ensure 'Modify an object label' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRelabelPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRelabelPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.32" + Task = "(L1) Ensure 'Modify firmware environment values' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.33" + Task = "(L1) Ensure 'Perform volume maintenance tasks' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.34" + Task = "(L1) Ensure 'Profile single process' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.35" + Task = "(L1) Ensure 'Profile system performance' is set to 'Administrators, NT SERVICE\WdiServiceHost'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemProfilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeSystemProfilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.36" + Task = "(L1) Ensure 'Replace a process level token' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAssignPrimaryTokenPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeAssignPrimaryTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.37" + Task = "(L1) Ensure 'Restore files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.38" + Task = "(L1) Ensure 'Shut down the system' is set to 'Administrators, Users'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-545" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.39" + Task = "(L1) Ensure 'Take ownership of files or other objects' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 7-CIS-3.1.0#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 7-CIS-3.1.0#AccountPolicies.ps1 new file mode 100644 index 0000000..d18b2b2 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 7-CIS-3.1.0#AccountPolicies.ps1 @@ -0,0 +1,255 @@ +[AuditTest] @{ + Id = "1.1.1" + Task = "(L1) Ensure 'Enforce password history' is set to '24 or more password(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "(L1) Ensure 'Maximum password age' is set to '60 or fewer days, but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 60 -or $setPolicy -le 0)) { + if($setPolicy -eq -1){ #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 60 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "(L1) Ensure 'Minimum password age' is set to '1 or more day(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 1)) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "(L1) Ensure 'Minimum password length' is set to '14 or more character(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.5" + Task = "(L1) Ensure 'Password must meet complexity requirements' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.6" + Task = "(L1) Ensure 'Store passwords using reversible encryption' is set to 'Disabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "(L1) Ensure 'Account lockout duration' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "(L1) Ensure 'Account lockout threshold' is set to '10 or fewer invalid logon attempt(s), but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 10 -or $setPolicy -le 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 10 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.3" + Task = "(L1) Ensure 'Reset account lockout counter after' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 7-CIS-3.1.0#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 7-CIS-3.1.0#AuditPolicies.ps1 new file mode 100644 index 0000000..701ef72 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 7-CIS-3.1.0#AuditPolicies.ps1 @@ -0,0 +1,1388 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "17.1.1" + Task = "(L1) Ensure 'Audit Credential Validation' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.1" + Task = "(L1) Ensure 'Audit Application Group Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Application Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Application Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Application Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.2" + Task = "(L1) Ensure 'Audit Computer Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Computer Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Computer Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Computer Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.3" + Task = "(L1) Ensure 'Audit Other Account Management Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.4" + Task = "(L1) Ensure 'Audit Security Group Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.5" + Task = "(L1) Ensure 'Audit User Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.1" + Task = "(L1) Ensure 'Audit Process Creation' is set to 'Success'" + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.1" + Task = "(L1) Ensure 'Audit Account Lockout' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.2" + Task = "(L1) Ensure 'Audit Logoff' is set to 'Success'" + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.3" + Task = "(L1) Ensure 'Audit Logon' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.4" + Task = "(L1) Ensure 'Audit Other Logon/Logoff Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.5" + Task = "(L1) Ensure 'Audit Special Logon' is set to 'Success'" + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.1" + Task = "(L1) Ensure 'Audit File Share' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.2" + Task = "(L1) Ensure 'Audit Other Object Access Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.1" + Task = "(L1) Ensure 'Audit Audit Policy Change' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.2" + Task = "(L1) Ensure 'Audit Authentication Policy Change' is set to 'Success'" + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.3" + Task = "(L1) Ensure 'Audit Authorization Policy Change' is set to 'Success'" + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.8.1" + Task = "(L1) Ensure 'Audit Sensitive Privilege Use' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.1" + Task = "(L1) Ensure 'Audit IPsec Driver' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Ipsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Ipsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Ipsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.2" + Task = "(L1) Ensure 'Audit Other System Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.3" + Task = "(L1) Ensure 'Audit Security State Change' is set to 'Success'" + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.4" + Task = "(L1) Ensure 'Audit Security System Extension' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.5" + Task = "(L1) Ensure 'Audit System Integrity' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows 7-CIS-3.1.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows 7-CIS-3.1.0#RegistrySettings.ps1 new file mode 100644 index 0000000..3488536 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows 7-CIS-3.1.0#RegistrySettings.ps1 @@ -0,0 +1,10042 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "2.3.1.3" + Task = "(L1) Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.1" + Task = "(L1) Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.2" + Task = "(L1) Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "CrashOnAuditFail" ` + | Select-Object -ExpandProperty "CrashOnAuditFail" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4.1" + Task = "(L1) Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators and Interactive Users'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AllocateDASD" ` + | Select-Object -ExpandProperty "AllocateDASD" + + if ($regValue -ne "2") { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4.2" + Task = "(L2) Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.1" + Task = "(L1) Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.2" + Task = "(L1) Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.3" + Task = "(L1) Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.4" + Task = "(L1) Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.5" + Task = "(L1) Ensure 'Domain member: Maximum machine account password age' is set to '30 or fewer days, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if (($regValue -le 0 -or $regValue -gt 30)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x > 0 and x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.6" + Task = "(L1) Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.1" + Task = "(L1) Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.2" + Task = "(L1) Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.3" + Task = "(L1) Configure 'Interactive logon: Message text for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.4" + Task = "(L1) Configure 'Interactive logon: Message title for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.5" + Task = "(L2) Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "CachedLogonsCount" ` + | Select-Object -ExpandProperty "CachedLogonsCount" + + if ($regValue -notmatch "^[43210]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[43210]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.6" + Task = "(L1) Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if (($regValue -gt 14 -or $regValue -lt 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 14 and x >= 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.7" + Task = "(L1) Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -notmatch "^(1|2|3)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(1|2|3)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.8.1" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.2" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.3" + Task = "(L1) Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.1" + Task = "(L1) Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if (($regValue -gt 15 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.2" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.3" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.4" + Task = "(L1) Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "enableforcedlogoff" ` + | Select-Object -ExpandProperty "enableforcedlogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.5" + Task = "(L1) Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "SMBServerNameHardeningLevel" ` + | Select-Object -ExpandProperty "SMBServerNameHardeningLevel" + + if (($regValue -lt 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.2" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.3" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.4" + Task = "(L1) Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.5" + Task = "(L1) Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.6" + Task = "(L1) Ensure 'Network access: Named Pipes that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + $reference = @( + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.7" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\ProductOptions" + "System\CurrentControlSet\Control\Server Applications" + "Software\Microsoft\Windows NT\CurrentVersion" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\ProductOptions System\CurrentControlSet\Control\Server Applications Software\Microsoft\Windows NT\CurrentVersion" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.8" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9" + Task = "(L1) Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.11" + Task = "(L1) Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.1" + Task = "(L1) Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.2" + Task = "(L1) Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.3" + Task = "(L1) Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.4" + Task = "(L1) Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if (($regValue -ne 2147483644) -and ($regValue -ne 2147483640)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2147483644 or x == 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.5" + Task = "(L1) Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.7" + Task = "(L1) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM&NTLM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.8" + Task = "(L1) Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if (($regValue -lt 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.9" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.10" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.14.1" + Task = "(L2) Ensure 'System cryptography: Force strong key protection for user keys stored on the computer' is set to 'User is prompted when the key is first used' or higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography" ` + -Name "ForceKeyProtection" ` + | Select-Object -ExpandProperty "ForceKeyProtection" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.1" + Task = "(L1) Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.2" + Task = "(L1) Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.1" + Task = "(L1) Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.2" + Task = "(L1) Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableUIADesktopToggle" ` + | Select-Object -ExpandProperty "EnableUIADesktopToggle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.3" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.4" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.5" + Task = "(L1) Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.6" + Task = "(L1) Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.7" + Task = "(L1) Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.8" + Task = "(L1) Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.9" + Task = "(L1) Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1" + Task = "(L2) Ensure 'Bluetooth Support Service (bthserv)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bthserv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2" + Task = "(L1) Ensure 'Computer Browser (Browser)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.3" + Task = "(L1) Ensure 'HomeGroup Listener (HomeGroupListener)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HomeGroupListener" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.4" + Task = "(L1) Ensure 'HomeGroup Provider (HomeGroupProvider)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HomeGroupProvider" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.5" + Task = "(L1) Ensure 'IIS Admin Service (IISADMIN)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IISADMIN" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.6" + Task = "(L1) Ensure 'Internet Connection Sharing (ICS) (SharedAccess) ' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.7" + Task = "(L2) Ensure 'Link-Layer Topology Discovery Mapper (lltdsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lltdsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.8" + Task = "(L1) Ensure 'Media Center Extender Service (Mcx2Svc)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Mcx2Svc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.9" + Task = "(L1) Ensure 'Microsoft FTP Service (FTPSVC)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FTPSVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.10" + Task = "(L2) Ensure 'Microsoft iSCSI Initiator Service (MSiSCSI)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSiSCSI" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.11" + Task = "(L2) Ensure 'Peer Name Resolution Protocol (PNRPsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.12" + Task = "(L2) Ensure 'Peer Networking Grouping (p2psvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2psvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.13" + Task = "(L2) Ensure 'Peer Networking Identity Manager (p2pimsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2pimsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.14" + Task = "(L2) Ensure 'PNRP Machine Name Publication Service (PNRPAutoReg)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPAutoReg" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.15" + Task = "(L2) Ensure 'Problem Reports and Solutions Control Panel Support (wercplsupport)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wercplsupport" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.16" + Task = "(L2) Ensure 'Remote Access Auto Connection Manager (RasAuto)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasAuto" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.17" + Task = "(L2) Ensure 'Remote Desktop Configuration (SessionEnv)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SessionEnv" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.18" + Task = "(L2) Ensure 'Remote Desktop Services (TermService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.19" + Task = "(L2) Ensure 'Remote Desktop Services UserMode Port Redirector (UmRdpService)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UmRdpService" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.20" + Task = "(L1) Ensure 'Remote Procedure Call (RPC) Locator (RpcLocator)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcLocator" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.21" + Task = "(L2) Ensure 'Remote Registry (RemoteRegistry)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteRegistry" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.22" + Task = "(L1) Ensure 'Routing and Remote Access (RemoteAccess)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.23" + Task = "(L2) Ensure 'Server (LanmanServer)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.24" + Task = "(L1) Ensure 'Simple TCP/IP Services (simptcp)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\simptcp" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.25" + Task = "(L2) Ensure 'SNMP Service (SNMP)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SNMP" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.26" + Task = "(L1) Ensure 'SSDP Discovery (SSDPSRV)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SSDPSRV" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.27" + Task = "(L1) Ensure 'Telnet (TlntSvr)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TlntSvr" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.28" + Task = "(L1) Ensure 'UPnP Device Host (upnphost)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\upnphost" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.29" + Task = "(L1) Ensure 'Web Management Service (WMSvc)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.30" + Task = "(L1) Ensure 'Windows CardSpace (idsvc)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\idsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.31" + Task = "(L2) Ensure 'Windows Error Reporting Service (WerSvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WerSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.32" + Task = "(L2) Ensure 'Windows Event Collector (Wecsvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Wecsvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.33" + Task = "(L1) Ensure 'Windows Media Center Receiver Service (ehRecvr)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ehRecvr" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.34" + Task = "(L1) Ensure 'Windows Media Center Scheduler Service (ehSched)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ehSched" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.35" + Task = "(L1) Ensure 'Windows Media Player Network Sharing Service (WMPNetworkSvc)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMPNetworkSvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.36" + Task = "(L2) Ensure 'Windows Remote Management (WS-Management) (WinRM)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinRM" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.37" + Task = "(L1) Ensure 'WinHTTP Web Proxy Auto-Discovery Service (WinHttpAutoProxySvc)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinHttpAutoProxySvc" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.38" + Task = "(L1) Ensure 'World Wide Web Publishing Service (W3SVC)' is set to 'Disabled' or 'Not Installed'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.1.1" + Task = "(L1) Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.2" + Task = "(L1) Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.3" + Task = "(L1) Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.4" + Task = "(L1) Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.5" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\domainfw.log'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SYSTEMROOT%\System32\logfiles\firewall\domainfw.log"; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.6" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.7" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.8" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.1" + Task = "(L1) Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.2" + Task = "(L1) Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.3" + Task = "(L1) Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.4" + Task = "(L1) Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.5" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\privatefw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\privatefw.log"; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.6" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.7" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.8" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.1" + Task = "(L1) Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.2" + Task = "(L1) Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.3" + Task = "(L1) Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.4" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.5" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.6" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.7" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\publicfw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\publicfw.log"; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.8" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.9" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.10" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "18.2.2" + Task = "(L1) Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "PwdExpirationProtectionEnabled" ` + | Select-Object -ExpandProperty "PwdExpirationProtectionEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.2.3" + Task = "(L1) Ensure 'Enable Local Admin Password Management' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "AdmPwdEnabled" ` + | Select-Object -ExpandProperty "AdmPwdEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.2.4" + Task = "(L1) Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "PasswordComplexity" ` + | Select-Object -ExpandProperty "PasswordComplexity" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.2.5" + Task = "(L1) Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "PasswordLength" ` + | Select-Object -ExpandProperty "PasswordLength" + + if (($regValue -lt 15)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.2.6" + Task = "(L1) Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "PasswordAgeDays" ` + | Select-Object -ExpandProperty "PasswordAgeDays" + + if (($regValue -gt 30)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.1" + Task = "(L1) Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.3" + Task = "(L1) Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.4" + Task = "(L1) Ensure 'Configure SMB v1 server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.5" + Task = "(L1) Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.6" + Task = "(L1) Ensure 'WDigest Authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.1" + Task = "(L1) Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.2" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.3" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.4" + Task = "(L2) Ensure 'MSS: (DisableSavePassword) Prevent the dial-up password from being saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\RasMan\Parameters" ` + -Name "disablesavepassword" ` + | Select-Object -ExpandProperty "disablesavepassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.5" + Task = "(L1) Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.6" + Task = "(L2) Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "KeepAliveTime" ` + | Select-Object -ExpandProperty "KeepAliveTime" + + if ($regValue -ne 300000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 300000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.7" + Task = "(L1) Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.8" + Task = "(L2) Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "PerformRouterDiscovery" ` + | Select-Object -ExpandProperty "PerformRouterDiscovery" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.9" + Task = "(L1) Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.10" + Task = "(L1) Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScreenSaverGracePeriod" ` + | Select-Object -ExpandProperty "ScreenSaverGracePeriod" + + if (($regValue -gt 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.11" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.12" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.13" + Task = "(L1) Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security" ` + -Name "WarningLevel" ` + | Select-Object -ExpandProperty "WarningLevel" + + if (($regValue -gt 90)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 90" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.4.1" + Task = "(L1) Set 'NetBIOS node type' to 'P-node' (Ensure NetBT Parameter 'NodeType' is set to '0x2 (2)')" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.4.2" + Task = "(L1) Ensure 'Turn off multicast name resolution' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.10.2" + Task = "(L2) Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Peernet" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.11.2" + Task = "(L1) Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.11.3" + Task = "(L1) Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_StdDomainUserSetLocation" ` + | Select-Object -ExpandProperty "NC_StdDomainUserSetLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.19.2.1" + Task = "(L2) Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "DisabledComponents" ` + | Select-Object -ExpandProperty "DisabledComponents" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.20.2" + Task = "(L2) Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\UI" ` + -Name "DisableWcnUi" ` + | Select-Object -ExpandProperty "DisableWcnUi" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.3.1" + Task = "(L1) Ensure 'Include command line in process creation events' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.7.1.1" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClasses" ` + | Select-Object -ExpandProperty "DenyDeviceClasses" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.7.1.3" + Task = "(BL) Ensure 'Prevent installation of devices using drivers that match these device setup classes: Also apply to matching devices that are already installed.' is set to 'True' (checked)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions" ` + -Name "DenyDeviceClassesRetroactive" ` + | Select-Object -ExpandProperty "DenyDeviceClassesRetroactive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.7.2" + Task = "(L1) Ensure 'Allow remote access to the Plug and Play interface' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceInstall\Settings" ` + -Name "AllowRemoteRPC" ` + | Select-Object -ExpandProperty "AllowRemoteRPC" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.21.2" + Task = "(L1) Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.21.3" + Task = "(L1) Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.21.4" + Task = "(L1) Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableBkGndGroupPolicy" ` + | Select-Object -ExpandProperty "DisableBkGndGroupPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.1" + Task = "(L1) Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.2" + Task = "(L2) Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TabletPC" ` + -Name "PreventHandwritingDataSharing" ` + | Select-Object -ExpandProperty "PreventHandwritingDataSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.3" + Task = "(L2) Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HandwritingErrorReports" ` + -Name "PreventHandwritingErrorReports" ` + | Select-Object -ExpandProperty "PreventHandwritingErrorReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.4" + Task = "(L2) Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Internet Connection Wizard" ` + -Name "ExitOnMSICW" ` + | Select-Object -ExpandProperty "ExitOnMSICW" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.5" + Task = "(L1) Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.6" + Task = "(L2) Ensure 'Turn off Internet File Association service' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInternetOpenWith" ` + | Select-Object -ExpandProperty "NoInternetOpenWith" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.7" + Task = "(L1) Ensure 'Turn off printing over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.8" + Task = "(L2) Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Registration Wizard Control" ` + -Name "NoRegistration" ` + | Select-Object -ExpandProperty "NoRegistration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.9" + Task = "(L2) Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SearchCompanion" ` + -Name "DisableContentFileUpdates" ` + | Select-Object -ExpandProperty "DisableContentFileUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.10" + Task = "(L2) Ensure 'Turn off the `"Order Prints`" picture task' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoOnlinePrintsWizard" ` + | Select-Object -ExpandProperty "NoOnlinePrintsWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.11" + Task = "(L2) Ensure 'Turn off the `"Publish to Web`" task for files and folders' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoPublishingWizard" ` + | Select-Object -ExpandProperty "NoPublishingWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.12" + Task = "(L2) Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Messenger\Client" ` + -Name "CEIP" ` + | Select-Object -ExpandProperty "CEIP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.22.1.13" + Task = "(L2) Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SQMClient\Windows" ` + -Name "CEIPEnable" ` + | Select-Object -ExpandProperty "CEIPEnable" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.27.1" + Task = "(L1) Ensure 'Always use classic logon' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LogonType" ` + | Select-Object -ExpandProperty "LogonType" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.33.6.1" + Task = "(BL) Ensure 'Allow standby states (S1-S3) when sleeping (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.33.6.2" + Task = "(BL) Ensure 'Allow standby states (S1-S3) when sleeping (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\abfc2519-3608-4c2a-94ea-171b0ed546ab" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.33.6.3" + Task = "(L1) Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.33.6.4" + Task = "(L1) Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.35.1" + Task = "(L1) Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.35.2" + Task = "(L1) Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.36.1" + Task = "(L1) Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "EnableAuthEpResolution" ` + | Select-Object -ExpandProperty "EnableAuthEpResolution" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.36.2" + Task = "(L1) Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.44.5.1" + Task = "(L2) Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.44.11.1" + Task = "(L2) Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d}" ` + -Name "ScenarioExecutionEnabled" ` + | Select-Object -ExpandProperty "ScenarioExecutionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.49.1.1" + Task = "(L2) Ensure 'Enable Windows NTP Client' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.49.1.2" + Task = "(L2) Ensure 'Enable Windows NTP Server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.8.1" + Task = "(L1) Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.8.2" + Task = "(L1) Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.8.3" + Task = "(L1) Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.1.1" + Task = "(BL) Ensure 'Allow access to BitLocker-protected fixed data drives from earlier versions of Windows' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVDiscoveryVolumeType" ` + | Select-Object -ExpandProperty "FDVDiscoveryVolumeType" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: This value should be empty." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.1.2" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecovery" ` + | Select-Object -ExpandProperty "FDVRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.1.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Allow data recovery agent' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVManageDRA" ` + | Select-Object -ExpandProperty "FDVManageDRA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.1.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Recovery Password' is set to 'Enabled: Allow 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecoveryPassword" ` + | Select-Object -ExpandProperty "FDVRecoveryPassword" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.1.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Recovery Key' is set to 'Enabled: Allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRecoveryKey" ` + | Select-Object -ExpandProperty "FDVRecoveryKey" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.1.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVHideRecoveryPage" ` + | Select-Object -ExpandProperty "FDVHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.1.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Save BitLocker recovery information to AD DS for fixed data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "FDVActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.1.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Configure storage of BitLocker recovery information to AD DS' is set to 'Enabled: Backup recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "FDVActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.1.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected fixed drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for fixed data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "FDVRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "FDVRequireActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.1.10" + Task = "(BL) Ensure 'Configure use of passwords for fixed data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVPassphrase" ` + | Select-Object -ExpandProperty "FDVPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.1.11" + Task = "(BL) Ensure 'Configure use of smart cards on fixed data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVAllowUserCert" ` + | Select-Object -ExpandProperty "FDVAllowUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.1.12" + Task = "(BL) Ensure 'Configure use of smart cards on fixed data drives: Require use of smart cards on fixed data drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "FDVEnforceUserCert" ` + | Select-Object -ExpandProperty "FDVEnforceUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.1" + Task = "(BL) Ensure 'Allow enhanced PINs for startup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "UseEnhancedPin" ` + | Select-Object -ExpandProperty "UseEnhancedPin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.2" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecovery" ` + | Select-Object -ExpandProperty "OSRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Allow data recovery agent' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSManageDRA" ` + | Select-Object -ExpandProperty "OSManageDRA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Recovery Password' is set to 'Enabled: Require 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecoveryPassword" ` + | Select-Object -ExpandProperty "OSRecoveryPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Recovery Key' is set to 'Enabled: Do not allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRecoveryKey" ` + | Select-Object -ExpandProperty "OSRecoveryKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSHideRecoveryPage" ` + | Select-Object -ExpandProperty "OSHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Save BitLocker recovery information to AD DS for operating system drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "OSActiveDirectoryBackup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Configure storage of BitLocker recovery information to AD DS:' is set to 'Enabled: Store recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "OSActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected operating system drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for operating system drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "OSRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "OSRequireActiveDirectoryBackup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.10" + Task = "(BL) Ensure 'Configure minimum PIN length for startup' is set to 'Enabled: 7 or more characters'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "MinimumPIN" ` + | Select-Object -ExpandProperty "MinimumPIN" + + if (($regValue -lt 7)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 7" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.11" + Task = "(BL) Ensure 'Require additional authentication at startup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseAdvancedStartup" ` + | Select-Object -ExpandProperty "UseAdvancedStartup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.12" + Task = "(BL) Ensure 'Require additional authentication at startup: Allow BitLocker without a compatible TPM' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "EnableBDEWithNoTPM" ` + | Select-Object -ExpandProperty "EnableBDEWithNoTPM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.13" + Task = "(BL) Ensure 'Require additional authentication at startup: Configure TPM startup:' is set to 'Enabled: Do not allow TPM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPM" ` + | Select-Object -ExpandProperty "UseTPM" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.14" + Task = "(BL) Ensure 'Require additional authentication at startup: Configure TPM startup PIN:' is set to 'Enabled: Require startup PIN with TPM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPMPIN" ` + | Select-Object -ExpandProperty "UseTPMPIN" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.15" + Task = "(BL) Ensure 'Require additional authentication at startup: Configure TPM startup key:' is set to 'Enabled: Do not allow startup key with TPM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPMKey" ` + | Select-Object -ExpandProperty "UseTPMKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.2.16" + Task = "(BL) Ensure 'Require additional authentication at startup: Configure TPM startup key and PIN:' is set to 'Enabled: Do not allow startup key and PIN with TPM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "UseTPMKeyPIN" ` + | Select-Object -ExpandProperty "UseTPMKeyPIN" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.1" + Task = "(BL) Ensure 'Allow access to BitLocker-protected removable data drives from earlier versions of Windows' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVDiscoveryVolumeType" ` + | Select-Object -ExpandProperty "RDVDiscoveryVolumeType" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: ''" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.2" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecovery" ` + | Select-Object -ExpandProperty "RDVRecovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.3" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Allow data recovery agent' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVManageDRA" ` + | Select-Object -ExpandProperty "RDVManageDRA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.4" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Recovery Password' is set to 'Enabled: Do not allow 48-digit recovery password'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecoveryPassword" ` + | Select-Object -ExpandProperty "RDVRecoveryPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.5" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Recovery Key' is set to 'Enabled: Do not allow 256-bit recovery key'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRecoveryKey" ` + | Select-Object -ExpandProperty "RDVRecoveryKey" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.6" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Omit recovery options from the BitLocker setup wizard' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVHideRecoveryPage" ` + | Select-Object -ExpandProperty "RDVHideRecoveryPage" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.7" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Save BitLocker recovery information to AD DS for removable data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "RDVActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.8" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Configure storage of BitLocker recovery information to AD DS:' is set to 'Enabled: Backup recovery passwords and key packages'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVActiveDirectoryInfoToStore" ` + | Select-Object -ExpandProperty "RDVActiveDirectoryInfoToStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.9" + Task = "(BL) Ensure 'Choose how BitLocker-protected removable drives can be recovered: Do not enable BitLocker until recovery information is stored to AD DS for removable data drives' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "RDVRequireActiveDirectoryBackup" ` + | Select-Object -ExpandProperty "RDVRequireActiveDirectoryBackup" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.10" + Task = "(BL) Ensure 'Configure use of passwords for removable data drives' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVPassphrase" ` + | Select-Object -ExpandProperty "RDVPassphrase" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.11" + Task = "(BL) Ensure 'Configure use of smart cards on removable data drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVAllowUserCert" ` + | Select-Object -ExpandProperty "RDVAllowUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.12" + Task = "(BL) Ensure 'Configure use of smart cards on removable data drives: Require use of smart cards on removable data drives' is set to 'Enabled: True'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVEnforceUserCert" ` + | Select-Object -ExpandProperty "RDVEnforceUserCert" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.13" + Task = "(BL) Ensure 'Deny write access to removable drives not protected by BitLocker' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\Microsoft\FVE" ` + -Name "RDVDenyWriteAccess" ` + | Select-Object -ExpandProperty "RDVDenyWriteAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.3.14" + Task = "(BL) Ensure 'Deny write access to removable drives not protected by BitLocker: Do not allow write access to devices configured in another organization' is set to 'Enabled: False'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\FVE" ` + -Name "RDVDenyCrossOrg" ` + | Select-Object -ExpandProperty "RDVDenyCrossOrg" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.11.4" + Task = "(BL) Ensure 'Choose drive encryption method and cipher strength (Windows Vista, Windows Server 2008, Windows 7, Windows Server 2008 R2)' is set to 'Enabled: AES 256-bit with Diffuser'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" ` + -Name "EncryptionMethod" ` + | Select-Object -ExpandProperty "EncryptionMethod" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.15.1" + Task = "(L1) Ensure 'Do not display the password reveal button' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.15.2" + Task = "(L1) Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.18.1" + Task = "(L1) Ensure 'Turn off desktop gadgets' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Windows\Sidebar" ` + -Name "TurnOffSidebar" ` + | Select-Object -ExpandProperty "TurnOffSidebar" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.18.2" + Task = "(L1) Ensure 'Turn Off user-installed desktop gadgets' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Windows\Sidebar" ` + -Name "TurnOffUserInstalledGadgets" ` + | Select-Object -ExpandProperty "TurnOffUserInstalledGadgets" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.1" + Task = "(L1) Ensure 'EMET 5.52' or higher is installed" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\EMET_Service" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.3" + Task = "(L1) Ensure 'Default Protections for Internet Explorer' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Internet Explorer\iexplore.exe" ` + | Select-Object -ExpandProperty "*\Internet Explorer\iexplore.exe" + + if ($regValue -ne "+EAF+ eaf_modules:mshtml.dll;flash*.ocx;jscript*.dll;vbscript.dll;vgx.dll +ASR asr_modules:npjpi*.dll;jp2iexp.dll;vgx.dll;msxml4*.dll;wshom.ocx;scrrun.dll;vbscript.dll asr_zones:1;2") { + return @{ + Message = "Registry value is '$regValue'. Expected: +EAF+ eaf_modules:mshtml.dll;flash*.ocx;jscript*.dll;vbscript.dll;vgx.dll +ASR asr_modules:npjpi*.dll;jp2iexp.dll;vgx.dll;msxml4*.dll;wshom.ocx;scrrun.dll;vbscript.dll asr_zones:1;2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.4" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Mozilla Thunderbird\thunderbird.exe" ` + | Select-Object -ExpandProperty "*\Mozilla Thunderbird\thunderbird.exe" + + if ($regValue -notmatch "^$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.5" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Java\jre*\bin\javaws.exe" ` + | Select-Object -ExpandProperty "*\Java\jre*\bin\javaws.exe" + + if ($regValue -ne "-HeapSpray") { + return @{ + Message = "Registry value is '$regValue'. Expected: -HeapSpray" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.6" + Task = "(L1) Ensure 'System ASLR' is set to 'Enabled: Application Opt-In'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\SysSettings" ` + -Name "ASLR" ` + | Select-Object -ExpandProperty "ASLR" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.7" + Task = "(L1) Ensure 'System DEP' is set to 'Enabled: Application Opt-Out'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\SysSettings" ` + -Name "DEP" ` + | Select-Object -ExpandProperty "DEP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.8" + Task = "(L1) Ensure 'System SEHOP' is set to 'Enabled: Application Opt-Out'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\SysSettings" ` + -Name "SEHOP" ` + | Select-Object -ExpandProperty "SEHOP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.1.1" + Task = "(L1) Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.1.2" + Task = "(L1) Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.2.1" + Task = "(L1) Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.2.2" + Task = "(L1) Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 196608)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.3.1" + Task = "(L1) Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.3.2" + Task = "(L1) Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.4.1" + Task = "(L1) Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.4.2" + Task = "(L1) Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.30.2" + Task = "(L1) Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.30.3" + Task = "(L1) Ensure 'Turn off heap termination on corruption' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.30.4" + Task = "(L1) Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.1" + Task = "(L1) Ensure 'Prevent the computer from joining a homegroup' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HomeGroup" ` + -Name "DisableHomeGroup" ` + | Select-Object -ExpandProperty "DisableHomeGroup" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.39.2" + Task = "(L2) Ensure 'Turn off location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.52.1" + Task = "(L1) Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.52.2" + Task = "(L1) Ensure 'Prevent the usage of OneDrive for file storage on Windows 8.1' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSync" ` + | Select-Object -ExpandProperty "DisableFileSync" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.2.2" + Task = "(L1) Ensure 'Do not allow passwords to be saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.2.1" + Task = "(L2) Ensure 'Allow users to connect remotely by using Remote Desktop Services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDenyTSConnections" ` + | Select-Object -ExpandProperty "fDenyTSConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.3.1" + Task = "(L2) Ensure 'Do not allow COM port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCcm" ` + | Select-Object -ExpandProperty "fDisableCcm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.3.2" + Task = "(L1) Ensure 'Do not allow drive redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.3.3" + Task = "(L2) Ensure 'Do not allow LPT port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLPT" ` + | Select-Object -ExpandProperty "fDisableLPT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.3.4" + Task = "(L2) Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisablePNPRedir" ` + | Select-Object -ExpandProperty "fDisablePNPRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.9.1" + Task = "(L1) Ensure 'Always prompt for password upon connection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.9.2" + Task = "(L1) Ensure 'Require secure RPC communication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.9.3" + Task = "(L1) Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.10.1" + Task = "(L2) Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxIdleTime" ` + | Select-Object -ExpandProperty "MaxIdleTime" + + if (($regValue -gt 900000 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900000 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.10.2" + Task = "(L2) Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxDisconnectionTime" ` + | Select-Object -ExpandProperty "MaxDisconnectionTime" + + if ($regValue -ne 60000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 60000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.11.1" + Task = "(L1) Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.11.2" + Task = "(L1) Ensure 'Do not use temporary folders per session' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "PerSessionTempDir" ` + | Select-Object -ExpandProperty "PerSessionTempDir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.59.1" + Task = "(L1) Ensure 'Prevent downloading of enclosures' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.60.2" + Task = "(L1) Ensure 'Allow indexing of encrypted files' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.76.3.1" + Task = "(L2) Ensure 'Join Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.76.14" + Task = "(L1) Ensure 'Turn off Windows Defender AntiVirus' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender" ` + -Name "DisableAntiSpyware" ` + | Select-Object -ExpandProperty "DisableAntiSpyware" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.81.2.1" + Task = "(L1) Ensure 'Configure Default consent' is set to 'Enabled: Always ask before sending data'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting\Consent" ` + -Name "DefaultConsent" ` + | Select-Object -ExpandProperty "DefaultConsent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.85.1" + Task = "(L1) Ensure 'Allow user control over installs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.85.2" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.85.3" + Task = "(L2) Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.95.1" + Task = "(L1) Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.95.2" + Task = "(L1) Ensure 'Turn on PowerShell Transcription' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" ` + -Name "EnableTranscripting" ` + | Select-Object -ExpandProperty "EnableTranscripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.97.1.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.97.1.2" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.97.1.3" + Task = "(L1) Ensure 'Disallow Digest authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.97.2.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.97.2.2" + Task = "(L2) Ensure 'Allow remote server management through WinRM' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowAutoConfig" ` + | Select-Object -ExpandProperty "AllowAutoConfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.97.2.3" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.97.2.4" + Task = "(L1) Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.98.1" + Task = "(L2) Ensure 'Allow Remote Shell Access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service\WinRS" ` + -Name "AllowRemoteShellAccess" ` + | Select-Object -ExpandProperty "AllowRemoteShellAccess" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.101.2" + Task = "(L1) Ensure 'Configure Automatic Updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.101.3" + Task = "(L1) Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.101.4" + Task = "(L1) Ensure 'Do not adjust default option to 'Install Updates and Shut Down' in Shut Down Windows dialog box' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAUAsDefaultShutdownOption" ` + | Select-Object -ExpandProperty "NoAUAsDefaultShutdownOption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.101.5" + Task = "(L1) Ensure 'Do not display 'Install Updates and Shut Down' option in Shut Down Windows dialog box' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAUShutdownOption" ` + | Select-Object -ExpandProperty "NoAUShutdownOption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.101.6" + Task = "(L1) Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings.ps1 new file mode 100644 index 0000000..be968cb --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings.ps1 @@ -0,0 +1,144 @@ +[AuditTest] @{ + Id = "2.0" + Task = "Ensure 'Enable DCOM Hardening' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\AppCompat" ` + -Name "RequireIntegrityActivationAuthenticationLevel" ` + | Select-Object -ExpandProperty "RequireIntegrityActivationAuthenticationLevel" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.1" + Task = "Ensure 'Raise Authentication Level' is set to 'Raise the authentication level for all non-anonymous activation requests from Windows-based DCOM clients'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\AppCompat" ` + -Name "RaiseActivationAuthenticationLevel" ` + | Select-Object -ExpandProperty "RaiseActivationAuthenticationLevel" + + if (($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.0" + Task = "IPv6 Configuration Policy: Prefer IPv4 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0x20 (32)')" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "DisabledComponents" ` + | Select-Object -ExpandProperty "DisabledComponents" + + if (($regValue -ne 32)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 32" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.0" + Task = "Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Prompt for credentials on the secure desktop'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights.ps1 new file mode 100644 index 0000000..701495e --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights.ps1 @@ -0,0 +1,102 @@ +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and + (Get-WindowsOptionalFeature -Online -FeatureName "Microsoft-Hyper-V").State -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "1.0" + Task = "Ensure 'Debug programs' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDebugPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#AccountPolicies.ps1 new file mode 100644 index 0000000..7dd897b --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#AccountPolicies.ps1 @@ -0,0 +1,255 @@ +[AuditTest] @{ + Id = "1.1.1" + Task = "(L1) Ensure 'Enforce password history' is set to '24 or more password(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "(L1) Ensure 'Maximum password age' is set to '365 or fewer days, but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -gt 365 -or $setPolicy -le 0) { + if($setPolicy -eq -1){ #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 365 and x > 0 " + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "(L1) Ensure 'Minimum password age' is set to '1 or more day(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -lt 1) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "(L1) Ensure 'Minimum password length' is set to '14 or more character(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.5" + Task = "(L1) Ensure 'Password must meet complexity requirements' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.6" + Task = "(L1) Ensure 'Store passwords using reversible encryption' is set to 'Disabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "(L1) Ensure 'Account lockout duration' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -lt 15 -or $setPolicy -gt 99999) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15 and x <= 99999" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "(L1) Ensure 'Account lockout threshold' is set to '5 or fewer invalid logon attempt(s), but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 5 -or $setPolicy -le 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 5 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.4" + Task = "(L1) Ensure 'Reset account lockout counter after' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -gt 99999 -or $setPolicy -lt 15) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x <= 99999 and x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#AuditPolicies.ps1 new file mode 100644 index 0000000..62e297d --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#AuditPolicies.ps1 @@ -0,0 +1,1922 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "17.1.1" + Task = "(L1) Ensure 'Audit Credential Validation' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.1.2" + Task = "(L1) Ensure 'Audit Kerberos Authentication Service' is set to 'Success and Failure' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Kerberos Authentication Service + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kerberos Authentication Service" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kerberos Authentication Service'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.1.3" + Task = "(L1) Ensure 'Audit Kerberos Service Ticket Operations' is set to 'Success and Failure' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Kerberos Service Ticket Operations + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kerberos Service Ticket Operations" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kerberos Service Ticket Operations'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.1" + Task = "(L1) Ensure 'Audit Application Group Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Application Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Application Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Application Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.2" + Task = "(L1) Ensure 'Audit Computer Account Management' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Computer Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Computer Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Computer Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.3" + Task = "(L1) Ensure 'Audit Distribution Group Management' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Distribution Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Distribution Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Distribution Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.4" + Task = "(L1) Ensure 'Audit Other Account Management Events' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.5" + Task = "(L1) Ensure 'Audit Security Group Management' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.6" + Task = "(L1) Ensure 'Audit User Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.1" + Task = "(L1) Ensure 'Audit Process Creation' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.4.1" + Task = "(L1) Ensure 'Audit Directory Service Access' is set to include 'Failure' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Directory Service Access + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Access" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Access'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.4.2" + Task = "(L1) Ensure 'Audit Directory Service Changes' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Directory Service Changes + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Changes" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Changes'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.1" + Task = "(L1) Ensure 'Audit Account Lockout' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.2" + Task = "(L1) Ensure 'Audit Logoff' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.3" + Task = "(L1) Ensure 'Audit Logon' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.4" + Task = "(L1) Ensure 'Audit Other Logon/Logoff Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.5" + Task = "(L1) Ensure 'Audit Special Logon' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.1" + Task = "(L1) Ensure 'Audit Detailed File Share' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.2" + Task = "(L1) Ensure 'Audit File Share' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.3" + Task = "(L1) Ensure 'Audit Other Object Access Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.4" + Task = "(L1) Ensure 'Audit Removable Storage' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.1" + Task = "(L1) Ensure 'Audit Audit Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.2" + Task = "(L1) Ensure 'Audit Authentication Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.3" + Task = "(L1) Ensure 'Audit Authorization Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.4" + Task = "(L1) Ensure 'Audit MPSSVC Rule-Level Policy Change' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Mpssvc Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Mpssvc Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Mpssvc Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.5" + Task = "(L1) Ensure 'Audit Other Policy Change Events' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.8.1" + Task = "(L1) Ensure 'Audit Sensitive Privilege Use' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.1" + Task = "(L1) Ensure 'Audit IPsec Driver' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Ipsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Ipsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Ipsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.2" + Task = "(L1) Ensure 'Audit Other System Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.3" + Task = "(L1) Ensure 'Audit Security State Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.4" + Task = "(L1) Ensure 'Audit Security System Extension' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.5" + Task = "(L1) Ensure 'Audit System Integrity' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#RegistrySettings.ps1 new file mode 100644 index 0000000..fd7f09a --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#RegistrySettings.ps1 @@ -0,0 +1,12455 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "2.3.1.1" + Task = "(L1) Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "NoConnectedUser" ` + | Select-Object -ExpandProperty "NoConnectedUser" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.3" + Task = "(L1) Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.1" + Task = "(L1) Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.2" + Task = "(L1) Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "CrashOnAuditFail" ` + | Select-Object -ExpandProperty "CrashOnAuditFail" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4.1" + Task = "(L1) Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AllocateDASD" ` + | Select-Object -ExpandProperty "AllocateDASD" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4.2" + Task = "(L1) Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.1" + Task = "(L1) Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SubmitControl" ` + | Select-Object -ExpandProperty "SubmitControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.2" + Task = "(L1) Ensure 'Domain controller: Allow vulnerable Netlogon secure channel connections' is set to 'Not Configured' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "vulnerablechannelallowlist" ` + | Select-Object -ExpandProperty "vulnerablechannelallowlist" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.3" + Task = "(L1) Ensure 'Domain controller: LDAP server channel binding token requirements' is set to 'Always' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LdapEnforceChannelBinding" ` + | Select-Object -ExpandProperty "LdapEnforceChannelBinding" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.4" + Task = "(L1) Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LDAPServerIntegrity" ` + | Select-Object -ExpandProperty "LDAPServerIntegrity" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.5" + Task = "(L1) Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RefusePasswordChange" ` + | Select-Object -ExpandProperty "RefusePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.1" + Task = "(L1) Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.2" + Task = "(L1) Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.3" + Task = "(L1) Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.4" + Task = "(L1) Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.5" + Task = "(L1) Ensure 'Domain member: Maximum machine account password age' is set to '30 or fewer days, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if ($regValue -le 0 -or $regValue -gt 30) { + return @{ + Message = "Registry value is '$regValue'. Expected: x > 0 and x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.6" + Task = "(L1) Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.1" + Task = "(L1) Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.2" + Task = "(L1) Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.3" + Task = "(L1) Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if ($regValue -gt 900 -or $regValue -eq 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.4" + Task = "(L1) Configure 'Interactive logon: Message text for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.5" + Task = "(L1) Configure 'Interactive logon: Message title for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.6" + Task = "(L2) Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "CachedLogonsCount" ` + | Select-Object -ExpandProperty "CachedLogonsCount" + + if ($regValue -notmatch "^[43210]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[43210]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.7" + Task = "(L1) Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if ($regValue -gt 14 -or $regValue -lt 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 14 and x >= 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.8" + Task = "(L1) Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ForceUnlockLogon" ` + | Select-Object -ExpandProperty "ForceUnlockLogon" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.9" + Task = "(L1) Ensure 'Interactive logon: Smart card removal behavior' is set to 1 - 'Lock Workstation' or 2 / 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -notmatch "^(1|2|3)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(1|2|3)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.8.1" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.2" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.3" + Task = "(L1) Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.1" + Task = "(L1) Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if ($regValue -gt 15) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.2" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.3" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.4" + Task = "(L1) Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "enableforcedlogoff" ` + | Select-Object -ExpandProperty "enableforcedlogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.5" + Task = "(L1) Ensure 'Microsoft network server: Server SPN target name validation level' is set to 1 - 'Accept if provided by client' or 2 - higher (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "SMBServerNameHardeningLevel" ` + | Select-Object -ExpandProperty "SMBServerNameHardeningLevel" + + if ($regValue -ne 1 -and $regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.2" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.3" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.4" + Task = "(L2) Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.5" + Task = "(L1) Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.6" + Task = "(L1) Configure 'Network access: Named Pipes that can be accessed anonymously' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + $reference = @( + "LSARPC" + "NETLOGON" + "SAMR" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: LSARPC NETLOGON SAMR" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.7" + Task = "(L1) Configure 'Network access: Named Pipes that can be accessed anonymously' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.8" + Task = "(L1) Configure 'Network access: Remotely accessible registry paths'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\ProductOptions" + "System\CurrentControlSet\Control\Server Applications" + "Software\Microsoft\Windows NT\CurrentVersion" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\ProductOptions System\CurrentControlSet\Control\Server Applications Software\Microsoft\Windows NT\CurrentVersion" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +$CARoleStatus = $null +$WINSStatus = $null +try { + $CARoleStatus = (Get-WindowsFeature -Name ADCS-Cert-Authority -ErrorAction Stop).Installed + $WINSStatus = (Get-WindowsFeature -Name WINS -ErrorAction Stop).Installed +} catch { + Write-Verbose "Get-WindowsFeature is not installed." +} +[AuditTest] @{ + Id = "2.3.10.9 A" + Task = "(L1) Configure 'Network access: Remotely accessible registry paths and sub-paths' [WINS Role Feature and CA Role Service NOT installed]" + Test = { + try { + if (($CARoleStatus -or $WINSStatus) -eq $true){ + return @{ + Message = "WINS Role Feature or CA Role Service are installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9 B" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured [CA Role Service installed]" + Test = { + try { + if ($CARoleStatus -eq $false){ + return @{ + Message = "CA Role Service NOT installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + "System\CurrentControlSet\Services\CertSvc" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog System\CurrentControlSet\Services\CertSvc" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9 C" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured [WINS Role Feature installed]" + Test = { + try { + if ($WINSStatus -eq $false){ + return @{ + Message = "WINS Role Feature NOT installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + "System\CurrentControlSet\Services\WINS" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog System\CurrentControlSet\Services\WINS" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.10" + Task = "(L1) Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.11" + Task = "(L1) Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "restrictremotesam" ` + | Select-Object -ExpandProperty "restrictremotesam" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.12" + Task = "(L1) Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionShares" ` + | Select-Object -ExpandProperty "NullSessionShares" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.13" + Task = "(L1) Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.1" + Task = "(L1) Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.2" + Task = "(L1) Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.3" + Task = "(L1) Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.4" + Task = "(L1) Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.5" + Task = "(L1) Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.7" + Task = "(L1) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.8" + Task = "(L1) Ensure 'Network security: LDAP client signing requirements' is set to 1 - 'Negotiate signing' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1 -and $regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.9" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.10" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.13.1" + Task = "(L1) Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ShutdownWithoutLogon" ` + | Select-Object -ExpandProperty "ShutdownWithoutLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.1" + Task = "(L1) Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.2" + Task = "(L1) Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.1" + Task = "(L1) Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.2" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 2 - 'Prompt for consent on the secure desktop' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if ($regValue -ne 1 -and $regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.3" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.4" + Task = "(L1) Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.5" + Task = "(L1) Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.6" + Task = "(L1) Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.7" + Task = "(L1) Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.8" + Task = "(L1) Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1" + Task = "(L1) Ensure 'Print Spooler (Spooler)' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2" + Task = "(L2) Ensure 'Print Spooler (Spooler)' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.1.1" + Task = "(L1) Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.2" + Task = "(L1) Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.3" + Task = "(L1) Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.4" + Task = "(L1) Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.5" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\domainfw.log'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\domainfw.log"; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.6" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.7" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.8" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.1" + Task = "(L1) Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.2" + Task = "(L1) Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.3" + Task = "(L1) Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.4" + Task = "(L1) Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.5" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\privatefw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\privatefw.log"; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.6" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.7" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.8" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.1" + Task = "(L1) Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.2" + Task = "(L1) Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.3" + Task = "(L1) Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.4" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.5" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.6" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.7" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\publicfw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\publicfw.log"; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.8" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.9" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.10" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "18.1.1.1" + Task = "(L1) Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.1.2" + Task = "(L1) Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.2" + Task = "(L1) Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "PwdExpirationProtectionEnabled" ` + | Select-Object -ExpandProperty "PwdExpirationProtectionEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.3" + Task = "(L1) Ensure 'Enable Local Admin Password Management' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft Services\AdmPwd" ` + -Name "AdmPwdEnabled" ` + | Select-Object -ExpandProperty "AdmPwdEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.4" + Task = "(L1) Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "PasswordComplexity" ` + | Select-Object -ExpandProperty "PasswordComplexity" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.5" + Task = "(L1) Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "PasswordLength" ` + | Select-Object -ExpandProperty "PasswordLength" + + if ($regValue -lt 15) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.6" + Task = "(L1) Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "PasswordAgeDays" ` + | Select-Object -ExpandProperty "PasswordAgeDays" + + if ($regValue -gt 30) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.1" + Task = "(L1) Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.2" + Task = "(L1) Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.3" + Task = "(L1) Ensure 'Configure SMB v1 server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.4" + Task = "(L1) Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.5" + Task = "(L1) Ensure 'LSA Protection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RunAsPPL" ` + | Select-Object -ExpandProperty "RunAsPPL" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.6" + Task = "(L1) Ensure 'NetBT NodeType configuration' is set to 'Enabled: P-node (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.7" + Task = "(L1) Ensure 'WDigest Authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.1" + Task = "(L1) Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.2" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.3" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.4" + Task = "(L1) Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.5" + Task = "(L2) Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "KeepAliveTime" ` + | Select-Object -ExpandProperty "KeepAliveTime" + + if ($regValue -ne 300000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 300000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.6" + Task = "(L1) Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.7" + Task = "(L2) Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "PerformRouterDiscovery" ` + | Select-Object -ExpandProperty "PerformRouterDiscovery" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.8" + Task = "(L1) Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.9" + Task = "(L1) Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScreenSaverGracePeriod" ` + | Select-Object -ExpandProperty "ScreenSaverGracePeriod" + + if ($regValue -notmatch "^[0-5]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[0-5]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.10" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.11" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.12" + Task = "(L1) Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security" ` + -Name "WarningLevel" ` + | Select-Object -ExpandProperty "WarningLevel" + + if ($regValue -gt 90) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 90" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.1" + Task = "(L1) Ensure 'Configure NetBIOS settings' is set to 2 - 'Enabled: Disable NetBIOS name resolution on public networks' (or 0 - Disable NetBIOS name resolution)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableNetBIOS" ` + | Select-Object -ExpandProperty "EnableNetBIOS" + + if ($regValue -ne 2 -and $regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2 or 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.2" + Task = "(L1) Ensure 'Turn off multicast name resolution' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 A" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnDomain" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 B" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnPublicNet" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 C" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (EnableLLTDIO)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableLLTDIO" ` + | Select-Object -ExpandProperty "EnableLLTDIO" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 D" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitLLTDIOOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitLLTDIOOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 A" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnDomain" ` + | Select-Object -ExpandProperty "AllowRspndrOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 B" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnPublicNet" ` + | Select-Object -ExpandProperty "AllowRspndrOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 C" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (EnableRspndr)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableRspndr" ` + | Select-Object -ExpandProperty "EnableRspndr" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 D" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitRspndrOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitRspndrOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.10.2" + Task = "(L2) Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Peernet" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.2" + Task = "(L1) Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.3" + Task = "(L1) Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_StdDomainUserSetLocation" ` + | Select-Object -ExpandProperty "NC_StdDomainUserSetLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 A" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`" and `"Require Integrity`" set for all NETLOGON and SYSVOL shares' (\\*\NETLOGON)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 B" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`" and `"Require Integrity`" set for all NETLOGON and SYSVOL shares' (\\*\SYSVOL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.19.2.1" + Task = "(L2) Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "DisabledComponents" ` + | Select-Object -ExpandProperty "DisabledComponents" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 A" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (EnableRegistrars)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "EnableRegistrars" ` + | Select-Object -ExpandProperty "EnableRegistrars" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 B" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableUPnPRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableUPnPRegistrar" ` + | Select-Object -ExpandProperty "DisableUPnPRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 C" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableInBand802DOT11Registrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableInBand802DOT11Registrar" ` + | Select-Object -ExpandProperty "DisableInBand802DOT11Registrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 D" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableFlashConfigRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableFlashConfigRegistrar" ` + | Select-Object -ExpandProperty "DisableFlashConfigRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 E" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableWPDRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableWPDRegistrar" ` + | Select-Object -ExpandProperty "DisableWPDRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.2" + Task = "(L2) Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\UI" ` + -Name "DisableWcnUi" ` + | Select-Object -ExpandProperty "DisableWcnUi" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.1" + Task = "(L1) Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled: 1 = Minimize simultaneous connections'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fMinimizeConnections" ` + | Select-Object -ExpandProperty "fMinimizeConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.2" + Task = "(L2) Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.1" + Task = "(L1) Ensure 'Allow Print Spooler to accept client connections' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "RegisterSpoolerRemoteRpcEndPoint" ` + | Select-Object -ExpandProperty "RegisterSpoolerRemoteRpcEndPoint" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.2" + Task = "(L1) Ensure 'Configure Redirection Guard' is set to 'Enabled: Redirection Guard Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "RedirectionGuardPolicy" ` + | Select-Object -ExpandProperty "RedirectionGuardPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.3" + Task = "(L1) Ensure 'Limits print driver installation to Administrators' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "RestrictDriverInstallationToAdministrators" ` + | Select-Object -ExpandProperty "RestrictDriverInstallationToAdministrators" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.4" + Task = "(L1) Ensure 'Manage processing of Queue-specific files' is set to 'Enabled: Limit Queue-specific files to Color profiles'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "CopyFilesPolicy" ` + | Select-Object -ExpandProperty "CopyFilesPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.5" + Task = "(L1) Ensure 'Point and Print Restrictions: When installing drivers for a new connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "NoWarningNoElevationOnInstall" ` + | Select-Object -ExpandProperty "NoWarningNoElevationOnInstall" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.6" + Task = "(L1) Ensure 'Point and Print Restrictions: When updating drivers for an existing connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "UpdatePromptSettings" ` + | Select-Object -ExpandProperty "UpdatePromptSettings" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.1.1" + Task = "(L2) Ensure 'Turn off notifications network usage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.3.1" + Task = "(L1) Ensure 'Include command line in process creation events' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.1" + Task = "(L1) Ensure 'Encryption Oracle Remediation' is set to 'Enabled: Force Updated Clients'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.2" + Task = "(L1) Ensure 'Prevent device metadata retrieval from the Internet' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" ` + -Name "PreventDeviceMetadataFromNetwork" ` + | Select-Object -ExpandProperty "PreventDeviceMetadataFromNetwork" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.13.1" + Task = "(L1) Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.2" + Task = "(L1) Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.3" + Task = "(L1) Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.4" + Task = "(L1) Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableBkGndGroupPolicy" ` + | Select-Object -ExpandProperty "DisableBkGndGroupPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.1" + Task = "(L1) Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.2" + Task = "(L2) Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TabletPC" ` + -Name "PreventHandwritingDataSharing" ` + | Select-Object -ExpandProperty "PreventHandwritingDataSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.3" + Task = "(L2) Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HandwritingErrorReports" ` + -Name "PreventHandwritingErrorReports" ` + | Select-Object -ExpandProperty "PreventHandwritingErrorReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.4" + Task = "(L2) Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Internet Connection Wizard" ` + -Name "ExitOnMSICW" ` + | Select-Object -ExpandProperty "ExitOnMSICW" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.5" + Task = "(L1) Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.6" + Task = "(L2) Ensure 'Turn off printing over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.7" + Task = "(L2) Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Registration Wizard Control" ` + -Name "NoRegistration" ` + | Select-Object -ExpandProperty "NoRegistration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.8" + Task = "(L2) Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SearchCompanion" ` + -Name "DisableContentFileUpdates" ` + | Select-Object -ExpandProperty "DisableContentFileUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.9" + Task = "(L2) Ensure 'Turn off the `"Order Prints`" picture task' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoOnlinePrintsWizard" ` + | Select-Object -ExpandProperty "NoOnlinePrintsWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.10" + Task = "(L2) Ensure 'Turn off the `"Publish to Web`" task for files and folders' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoPublishingWizard" ` + | Select-Object -ExpandProperty "NoPublishingWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.11" + Task = "(L2) Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Messenger\Client" ` + -Name "CEIP" ` + | Select-Object -ExpandProperty "CEIP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.12" + Task = "(L2) Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SQMClient\Windows" ` + -Name "CEIPEnable" ` + | Select-Object -ExpandProperty "CEIPEnable" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13 A" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (Disabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13 B" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (DoReport)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\PCHealth\ErrorReporting" ` + -Name "DoReport" ` + | Select-Object -ExpandProperty "DoReport" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.1" + Task = "(L2) Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Control Panel\International" ` + -Name "BlockUserInputMethodsForSignIn" ` + | Select-Object -ExpandProperty "BlockUserInputMethodsForSignIn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.1" + Task = "(L1) Ensure 'Do not display network selection UI' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.2" + Task = "(L1) Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontEnumerateConnectedUsers" ` + | Select-Object -ExpandProperty "DontEnumerateConnectedUsers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.3" + Task = "(L1) Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.4" + Task = "(L1) Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.5" + Task = "(L1) Ensure 'Turn off picture password sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "BlockDomainPicturePassword" ` + | Select-Object -ExpandProperty "BlockDomainPicturePassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.6" + Task = "(L1) Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.1" + Task = "(L1) Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.32.6.2" + Task = "(L1) Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.34.1" + Task = "(L1) Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.34.2" + Task = "(L1) Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.1" + Task = "(L1) Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "EnableAuthEpResolution" ` + | Select-Object -ExpandProperty "EnableAuthEpResolution" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.2" + Task = "(L2) Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.46.5.1" + Task = "(L2) Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.46.11.1" + Task = "(L2) Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d}" ` + -Name "ScenarioExecutionEnabled" ` + | Select-Object -ExpandProperty "ScenarioExecutionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.48.1" + Task = "(L2) Ensure 'Turn off the advertising ID' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" ` + -Name "DisabledByGroupPolicy" ` + | Select-Object -ExpandProperty "DisabledByGroupPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.50.1.1" + Task = "(L2) Ensure 'Enable Windows NTP Client' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.50.1.2" + Task = "(L2) Ensure 'Enable Windows NTP Server' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.5.1" + Task = "(L1) Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.1" + Task = "(L1) Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.2" + Task = "(L1) Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.3" + Task = "(L1) Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.1" + Task = "(L1) Ensure 'Do not display the password reveal button' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.2" + Task = "(L1) Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.1" + Task = "(L1) Ensure 'EMET 5.52' or higher is installed" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\EMET_Service" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.2 A" + Task = "(L1) Ensure 'Default Action and Mitigation Settings' is set to 'Enabled' (plus subsettings)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\SysSettings" ` + -Name "AntiDetours" ` + | Select-Object -ExpandProperty "AntiDetours" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.2 B" + Task = "(L1) Ensure 'Default Action and Mitigation Settings' is set to 'Enabled' (plus subsettings)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\SysSettings" ` + -Name "BannedFunctions" ` + | Select-Object -ExpandProperty "BannedFunctions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.2 C" + Task = "(L1) Ensure 'Default Action and Mitigation Settings' is set to 'Enabled' (plus subsettings)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\SysSettings" ` + -Name "DeepHooks" ` + | Select-Object -ExpandProperty "DeepHooks" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.2 D" + Task = "(L1) Ensure 'Default Action and Mitigation Settings' is set to 'Enabled' (plus subsettings)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\SysSettings" ` + -Name "ExploitAction" ` + | Select-Object -ExpandProperty "ExploitAction" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.3" + Task = "(L1) Ensure 'Default Protections for Internet Explorer' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Internet Explorer\iexplore.exe" ` + | Select-Object -ExpandProperty "*\Internet Explorer\iexplore.exe" + + if ($regValue -ne "+EAF+ eaf_modules:mshtml.dll;flash*.ocx;jscript*.dll;vbscript.dll;vgx.dll +ASR asr_modules:npjpi*.dll;jp2iexp.dll;vgx.dll;msxml4*.dll;wshom.ocx;scrrun.dll;vbscript.dll asr_zones:1;2") { + return @{ + Message = "Registry value is '$regValue'. Expected: +EAF+ eaf_modules:mshtml.dll;flash*.ocx;jscript*.dll;vbscript.dll;vgx.dll +ASR asr_modules:npjpi*.dll;jp2iexp.dll;vgx.dll;msxml4*.dll;wshom.ocx;scrrun.dll;vbscript.dll asr_zones:1;2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 A" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\7-Zip\7z.exe" ` + | Select-Object -ExpandProperty "*\7-Zip\7z.exe" + + if ($regValue -ne "-EAF") { + return @{ + Message = "Registry value is '$regValue'. Expected: -EAF" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 AA" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Windows Live\Photo Gallery\WLXPhotoGallery.exe" ` + | Select-Object -ExpandProperty "*\Windows Live\Photo Gallery\WLXPhotoGallery.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 AB" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Windows Live\Writer\WindowsLiveWriter.exe" ` + | Select-Object -ExpandProperty "*\Windows Live\Writer\WindowsLiveWriter.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 AC" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Windows Media Player\wmplayer.exe" ` + | Select-Object -ExpandProperty "*\Windows Media Player\wmplayer.exe" + + if ($regValue -ne "-EAF -MandatoryASLR") { + return @{ + Message = "Registry value is '$regValue'. Expected: -EAF -MandatoryASLR" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 AD" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\WinRAR\rar.exe" ` + | Select-Object -ExpandProperty "*\WinRAR\rar.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 AE" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\WinRAR\unrar.exe" ` + | Select-Object -ExpandProperty "*\WinRAR\unrar.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 AF" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\WinRAR\winrar.exe" ` + | Select-Object -ExpandProperty "*\WinRAR\winrar.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 AG" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\WinZip\winzip32.exe" ` + | Select-Object -ExpandProperty "*\WinZip\winzip32.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 AH" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\WinZip\winzip64.exe" ` + | Select-Object -ExpandProperty "*\WinZip\winzip64.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 B" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\7-Zip\7zG.exe" ` + | Select-Object -ExpandProperty "*\7-Zip\7zG.exe" + + if ($regValue -ne "-EAF") { + return @{ + Message = "Registry value is '$regValue'. Expected: -EAF" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 C" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\7-Zip\7zFM.exe" ` + | Select-Object -ExpandProperty "*\7-Zip\7zFM.exe" + + if ($regValue -ne "-EAF") { + return @{ + Message = "Registry value is '$regValue'. Expected: -EAF" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 D" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Adobe\Adobe Photoshop CS*\Photoshop.exe" ` + | Select-Object -ExpandProperty "*\Adobe\Adobe Photoshop CS*\Photoshop.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 E" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Foxit Reader\Foxit Reader.exe" ` + | Select-Object -ExpandProperty "*\Foxit Reader\Foxit Reader.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 F" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Google\Chrome\Application\chrome.exe" ` + | Select-Object -ExpandProperty "*\Google\Chrome\Application\chrome.exe" + + if ($regValue -ne "+EAF+ eaf_modules:chrome_child.dll") { + return @{ + Message = "Registry value is '$regValue'. Expected: +EAF+ eaf_modules:chrome_child.dll" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 G" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Google\Google Talk\googletalk.exe" ` + | Select-Object -ExpandProperty "*\Google\Google Talk\googletalk.exe" + + if ($regValue -ne "-DEP") { + return @{ + Message = "Registry value is '$regValue'. Expected: -DEP" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 H" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\iTunes\iTunes.exe" ` + | Select-Object -ExpandProperty "*\iTunes\iTunes.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 I" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Microsoft Lync\communicator.exe" ` + | Select-Object -ExpandProperty "*\Microsoft Lync\communicator.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 J" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\mIRC\mirc.exe" ` + | Select-Object -ExpandProperty "*\mIRC\mirc.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 K" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Mozilla Firefox\firefox.exe" ` + | Select-Object -ExpandProperty "*\Mozilla Firefox\firefox.exe" + + if ($regValue -ne "+EAF+ eaf_modules:mozjs.dll;xul.dll") { + return @{ + Message = "Registry value is '$regValue'. Expected: +EAF+ eaf_modules:mozjs.dll;xul.dll" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 L" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Mozilla Firefox\plugin-container.exe" ` + | Select-Object -ExpandProperty "*\Mozilla Firefox\plugin-container.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 M" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Mozilla Thunderbird\plugin-container.exe" ` + | Select-Object -ExpandProperty "*\Mozilla Thunderbird\plugin-container.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 N" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Mozilla Thunderbird\thunderbird.exe" ` + | Select-Object -ExpandProperty "*\Mozilla Thunderbird\thunderbird.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 O" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Opera\*\opera.exe" ` + | Select-Object -ExpandProperty "*\Opera\*\opera.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 P" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Opera\opera.exe" ` + | Select-Object -ExpandProperty "*\Opera\opera.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 Q" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Pidgin\pidgin.exe" ` + | Select-Object -ExpandProperty "*\Pidgin\pidgin.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 R" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\QuickTime\QuickTimePlayer.exe" ` + | Select-Object -ExpandProperty "*\QuickTime\QuickTimePlayer.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 S" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Real\RealPlayer\realconverter.exe" ` + | Select-Object -ExpandProperty "*\Real\RealPlayer\realconverter.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 T" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Real\RealPlayer\realplay.exe" ` + | Select-Object -ExpandProperty "*\Real\RealPlayer\realplay.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 U" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Safari\Safari.exe" ` + | Select-Object -ExpandProperty "*\Safari\Safari.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 V" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\SkyDrive\SkyDrive.exe" ` + | Select-Object -ExpandProperty "*\SkyDrive\SkyDrive.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 W" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Skype\Phone\Skype.exe" ` + | Select-Object -ExpandProperty "*\Skype\Phone\Skype.exe" + + if ($regValue -ne "-EAF") { + return @{ + Message = "Registry value is '$regValue'. Expected: -EAF" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 X" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\VideoLAN\VLC\vlc.exe" ` + | Select-Object -ExpandProperty "*\VideoLAN\VLC\vlc.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 Y" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Winamp\winamp.exe" ` + | Select-Object -ExpandProperty "*\Winamp\winamp.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.4 Z" + Task = "(L1) Ensure 'Default Protections for Popular Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Windows Live\Mail\wlmail.exe" ` + | Select-Object -ExpandProperty "*\Windows Live\Mail\wlmail.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 A" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Adobe\*\Reader\AcroRd32.exe" ` + | Select-Object -ExpandProperty "*\Adobe\*\Reader\AcroRd32.exe" + + if ($regValue -ne "+EAF+ eaf_modules:AcroRd32.dll;Acrofx32.dll;AcroForm.api") { + return @{ + Message = "Registry value is '$regValue'. Expected: +EAF+ eaf_modules:AcroRd32.dll;Acrofx32.dll;AcroForm.api" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 B" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Adobe\Acrobat*\Acrobat\Acrobat.exe" ` + | Select-Object -ExpandProperty "*\Adobe\Acrobat*\Acrobat\Acrobat.exe" + + if ($regValue -ne "+EAF+ eaf_modules:AcroRd32.dll;Acrofx32.dll;AcroForm.api") { + return @{ + Message = "Registry value is '$regValue'. Expected: +EAF+ eaf_modules:AcroRd32.dll;Acrofx32.dll;AcroForm.api" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 C" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Java\jre*\bin\java.exe" ` + | Select-Object -ExpandProperty "*\Java\jre*\bin\java.exe" + + if ($regValue -ne "-HeapSpray") { + return @{ + Message = "Registry value is '$regValue'. Expected: -HeapSpray" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 D" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Java\jre*\bin\javaw.exe" ` + | Select-Object -ExpandProperty "*\Java\jre*\bin\javaw.exe" + + if ($regValue -ne "-HeapSpray") { + return @{ + Message = "Registry value is '$regValue'. Expected: -HeapSpray" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 E" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Java\jre*\bin\javaws.exe" ` + | Select-Object -ExpandProperty "*\Java\jre*\bin\javaws.exe" + + if ($regValue -ne "-HeapSpray") { + return @{ + Message = "Registry value is '$regValue'. Expected: -HeapSpray" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 F" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\OFFICE1*\EXCEL.exe" ` + | Select-Object -ExpandProperty "*\OFFICE1*\EXCEL.exe" + + if ($regValue -ne "+ASR asr_modules:flash*.ocx") { + return @{ + Message = "Registry value is '$regValue'. Expected: +ASR asr_modules:flash*.ocx" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 G" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\OFFICE1*\INFOPATH.exe" ` + | Select-Object -ExpandProperty "*\OFFICE1*\INFOPATH.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 H" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\OFFICE1*\LYNC.exe" ` + | Select-Object -ExpandProperty "*\OFFICE1*\LYNC.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 I" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\OFFICE1*\MSACCESS.exe" ` + | Select-Object -ExpandProperty "*\OFFICE1*\MSACCESS.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 J" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\OFFICE1*\MSPUB.exe" ` + | Select-Object -ExpandProperty "*\OFFICE1*\MSPUB.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 K" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\OFFICE1*\OIS.exe" ` + | Select-Object -ExpandProperty "*\OFFICE1*\OIS.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 L" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\OFFICE1*\OUTLOOK.exe" ` + | Select-Object -ExpandProperty "*\OFFICE1*\OUTLOOK.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 M" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\OFFICE1*\POWERPNT.exe" ` + | Select-Object -ExpandProperty "*\OFFICE1*\POWERPNT.exe" + + if ($regValue -ne "+ASR asr_modules:flash*.ocx") { + return @{ + Message = "Registry value is '$regValue'. Expected: +ASR asr_modules:flash*.ocx" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 N" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\OFFICE1*\PPTVIEW.exe" ` + | Select-Object -ExpandProperty "*\OFFICE1*\PPTVIEW.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 O" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\OFFICE1*\VISIO.exe" ` + | Select-Object -ExpandProperty "*\OFFICE1*\VISIO.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 P" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\OFFICE1*\VPREVIEW.exe" ` + | Select-Object -ExpandProperty "*\OFFICE1*\VPREVIEW.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 Q" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\OFFICE1*\WINWORD.exe" ` + | Select-Object -ExpandProperty "*\OFFICE1*\WINWORD.exe" + + if ($regValue -ne "+ASR asr_modules:flash*.ocx") { + return @{ + Message = "Registry value is '$regValue'. Expected: +ASR asr_modules:flash*.ocx" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.5 R" + Task = "(L1) Ensure 'Default Protections for Recommended Software' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\Defaults" ` + -Name "*\Windows NT\Accessories\wordpad.exe" ` + | Select-Object -ExpandProperty "*\Windows NT\Accessories\wordpad.exe" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.6" + Task = "(L1) Ensure 'System ASLR' is set to 'Enabled: Application Opt-In'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\SysSettings" ` + -Name "ASLR" ` + | Select-Object -ExpandProperty "ASLR" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.7" + Task = "(L1) Ensure 'System DEP' is set to 'Enabled: Application Opt-Out'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\SysSettings" ` + -Name "DEP" ` + | Select-Object -ExpandProperty "DEP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.24.8" + Task = "(L1) Ensure 'System SEHOP' is set to 'Enabled: Application Opt-Out'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EMET\SysSettings" ` + -Name "SEHOP" ` + | Select-Object -ExpandProperty "SEHOP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.1.1" + Task = "(L1) Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.1.2" + Task = "(L1) Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.2.1" + Task = "(L1) Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.2.2" + Task = "(L1) Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.3.1" + Task = "(L1) Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.3.2" + Task = "(L1) Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.4.1" + Task = "(L1) Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.4.2" + Task = "(L1) Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.2" + Task = "(L1) Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.3" + Task = "(L1) Ensure 'Turn off heap termination on corruption' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.4" + Task = "(L1) Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.37.1.1" + Task = "(L2) Ensure 'Turn off Windows Location Provider' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableWindowsLocationProvider" ` + | Select-Object -ExpandProperty "DisableWindowsLocationProvider" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.37.2" + Task = "(L2) Ensure 'Turn off location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.5.1" + Task = "(L1) Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.5.2" + Task = "(L2) Ensure 'Join Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.1" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 A" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office communication application from creating child processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 B" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating executable content'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 C" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block abuse of exploited vulnerable signed drivers'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 D" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block execution of potentially obfuscated scripts'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 E" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from injecting code into other processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 F" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Adobe Reader from creating child processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 G" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block credential stealing from the Windows local security authority subsystem (lsass.exe)'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 H" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block untrusted and unsigned processes that run from USB'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 I" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block executable content from email client and webmail'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 J" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating child processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.1" + Task = "(L1) Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.2" + Task = "(L1) Ensure 'Turn off real-time protection' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.3" + Task = "(L1) Ensure 'Turn on behavior monitoring' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.4" + Task = "(L1) Ensure 'Turn on script scanning' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableScriptScanning" ` + | Select-Object -ExpandProperty "DisableScriptScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.12.1" + Task = "(L2) Ensure 'Configure Watson events' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" ` + -Name "DisableGenericReports" ` + | Select-Object -ExpandProperty "DisableGenericReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.1" + Task = "(L1) Ensure 'Scan removable drives' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.2" + Task = "(L1) Ensure 'Turn on e-mail scanning' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.16" + Task = "(L1) Ensure 'Turn off Microsoft Defender AntiVirus' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "DisableAntiSpyware" ` + | Select-Object -ExpandProperty "DisableAntiSpyware" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.51.1" + Task = "(L1) Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.51.2" + Task = "(L1) Ensure 'Prevent the usage of OneDrive for file storage on Windows 8.1' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSync" ` + | Select-Object -ExpandProperty "DisableFileSync" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.2.2" + Task = "(L1) Ensure 'Do not allow passwords to be saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.2.1" + Task = "(L2) Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fSingleSessionPerUser" ` + | Select-Object -ExpandProperty "fSingleSessionPerUser" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.1" + Task = "(L2) Ensure 'Do not allow COM port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCcm" ` + | Select-Object -ExpandProperty "fDisableCcm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.2" + Task = "(L1) Ensure 'Do not allow drive redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.3" + Task = "(L2) Ensure 'Do not allow LPT port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLPT" ` + | Select-Object -ExpandProperty "fDisableLPT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.4" + Task = "(L2) Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisablePNPRedir" ` + | Select-Object -ExpandProperty "fDisablePNPRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.1" + Task = "(L1) Ensure 'Always prompt for password upon connection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.2" + Task = "(L1) Ensure 'Require secure RPC communication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.3" + Task = "(L1) Ensure 'Require use of specific security layer for remote (RDP) connections' is set to 'Enabled: SSL'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SecurityLayer" ` + | Select-Object -ExpandProperty "SecurityLayer" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.4" + Task = "(L1) Ensure 'Require user authentication for remote connections by using Network Level Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "UserAuthentication" ` + | Select-Object -ExpandProperty "UserAuthentication" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.5" + Task = "(L1) Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.10.1" + Task = "(L2) Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less, but not Never (0)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxIdleTime" ` + | Select-Object -ExpandProperty "MaxIdleTime" + + if ($regValue -gt 900000 -or $regValue -eq 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900000 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.10.2" + Task = "(L2) Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxDisconnectionTime" ` + | Select-Object -ExpandProperty "MaxDisconnectionTime" + + if ($regValue -ne 60000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 60000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.11.1" + Task = "(L1) Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.11.2" + Task = "(L1) Ensure 'Do not use temporary folders per session' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "PerSessionTempDir" ` + | Select-Object -ExpandProperty "PerSessionTempDir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.1" + Task = "(L1) Ensure 'Prevent downloading of enclosures' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.2" + Task = "(L1) Ensure 'Allow indexing of encrypted files' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.3" + Task = "(L2) Ensure 'Set what information is shared in Search' is set to 'Enabled: Anonymous info'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "ConnectedSearchPrivacy" ` + | Select-Object -ExpandProperty "ConnectedSearchPrivacy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.2.1 A" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (EnableSmartScreen)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.2.1 B" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (ShellSmartScreenLevel)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.77.2.1" + Task = "(L1) Ensure 'Configure Default consent' is set to 'Enabled: Always ask before sending data'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting\Consent" ` + -Name "DefaultConsent" ` + | Select-Object -ExpandProperty "DefaultConsent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.77.3" + Task = "(L1) Ensure 'Automatically send memory dumps for OS-generated error reports' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "AutoApproveOSDumps" ` + | Select-Object -ExpandProperty "AutoApproveOSDumps" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.1" + Task = "(L1) Ensure 'Allow user control over installs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.2" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.3" + Task = "(L2) Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.82.1" + Task = "(L1) Ensure 'Sign-in and lock last interactive user automatically after a restart' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.87.1" + Task = "(L1) Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.87.2" + Task = "(L1) Ensure 'Turn on PowerShell Transcription' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" ` + -Name "EnableTranscripting" ` + | Select-Object -ExpandProperty "EnableTranscripting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.2" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.3" + Task = "(L1) Ensure 'Disallow Digest authentication' is set to 'Enabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.2" + Task = "(L2) Ensure 'Allow remote server management through WinRM' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowAutoConfig" ` + | Select-Object -ExpandProperty "AllowAutoConfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.3" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.4" + Task = "(L1) Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.90.1" + Task = "(L2) Ensure 'Allow Remote Shell Access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service\WinRS" ` + -Name "AllowRemoteShellAccess" ` + | Select-Object -ExpandProperty "AllowRemoteShellAccess" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.1.1" + Task = "(L1) Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.1" + Task = "(L1) Ensure 'Configure Automatic Updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.2" + Task = "(L1) Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.1.3.1" + Task = "(L1) Ensure 'Enable screen saver' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaveActive" ` + | Select-Object -ExpandProperty "ScreenSaveActive" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.1.3.2" + Task = "(L1) Ensure 'Password protect the screen saver' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaverIsSecure" ` + | Select-Object -ExpandProperty "ScreenSaverIsSecure" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.1.3.3" + Task = "(L1) Ensure 'Screen saver timeout' is set to 'Enabled: 900 seconds or fewer, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaveTimeOut" ` + | Select-Object -ExpandProperty "ScreenSaveTimeOut" + + if ($regValue -gt 900 -or $regValue -le 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x > 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.5.1.1" + Task = "(L1) Ensure 'Turn off toast notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.6.6.1.1" + Task = "(L2) Ensure 'Turn off Help Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Assistance\Client\1.0" ` + -Name "NoImplicitFeedback" ` + | Select-Object -ExpandProperty "NoImplicitFeedback" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.4.1" + Task = "(L1) Ensure 'Do not preserve zone information in file attachments' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.4.2" + Task = "(L1) Ensure 'Notify antivirus programs when opening attachments' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "ScanWithAntiVirus" ` + | Select-Object -ExpandProperty "ScanWithAntiVirus" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.25.1" + Task = "(L1) Ensure 'Prevent users from sharing files within their profile.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInplaceSharing" ` + | Select-Object -ExpandProperty "NoInplaceSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.40.1" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled' (AlwaysInstallElevated)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.42.2.1" + Task = "(L2) Ensure 'Prevent Codec Download' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\WindowsMediaPlayer" ` + -Name "PreventCodecDownload" ` + | Select-Object -ExpandProperty "PreventCodecDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#SecurityOptions.ps1 new file mode 100644 index 0000000..59b8d27 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#SecurityOptions.ps1 @@ -0,0 +1,133 @@ +[AuditTest] @{ + Id = "2.3.1.2" + Task = "(L1) Ensure 'Accounts: Guest account status' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.4" + Task = "(L1) Configure 'Accounts: Rename administrator account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption. Expected: ^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.5" + Task = "(L1) Configure 'Accounts: Rename guest account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption. Expected: ^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.1" + Task = "(L1) Ensure 'Network access: Allow anonymous SID/Name translation' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.6" + Task = "(L1) Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["ForceLogoffWhenHourExpire"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 1) { + return @{ + Message = "'ForceLogoffWhenHourExpire' currently set to: $setOption. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#UserRights.ps1 new file mode 100644 index 0000000..4b34271 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-CIS-3.0.0#UserRights.ps1 @@ -0,0 +1,1937 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE") { + if ($name -eq "Enterprise Admins") { + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins") { + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "2.2.1" + Task = "(L1) Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Authenticated Users, ENTERPRISE DOMAIN CONTROLLERS' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-11" + "S-1-5-32-544" + "S-1-5-9" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.3" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Authenticated Users' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-11" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.4" + Task = "(L1) Ensure 'Act as part of the operating system' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.5" + Task = "(L1) Ensure 'Add workstations to domain' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeMachineAccountPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeMachineAccountPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeMachineAccountPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.6" + Task = "(L1) Ensure 'Adjust memory quotas for a process' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseQuotaPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseQuotaPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseQuotaPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.7" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.8" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.9" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators, Remote Desktop Users' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.10" + Task = "(L1) Ensure 'Back up files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.11" + Task = "(L1) Ensure 'Change the system time' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemtimePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemtimePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemtimePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.12" + Task = "(L1) Ensure 'Change the time zone' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTimeZonePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTimeZonePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTimeZonePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.13" + Task = "(L1) Ensure 'Create a pagefile' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Ensure 'Create a token object' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.15" + Task = "(L1) Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.16" + Task = "(L1) Ensure 'Create permanent shared objects' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.17" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if ($hyperVStatus -ne "Enabled") { +[AuditTest] @{ + Id = "2.2.18" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators [Hyper-V-Feature NOT installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +} +else { +[AuditTest] @{ + Id = "2.2.18" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators, NT VIRTUAL MACHINE\Virtual Machines' [Hyper-V-Feature installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Debug programs' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + #No UserRights on System comparing to publisher recommendation + if ($null -eq $currentUserRights -and $identityAccounts.Count -gt 0) { + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if ($currentUserRights.Count -lt $identityAccounts.Count) { + $users = "" + foreach ($currentUser in $currentUserRights) { + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.20" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.21" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests, Local account and member of Administrators group' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + "S-1-5-114" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.22" + Task = "(L1) Ensure 'Deny log on as a batch job' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.23" + Task = "(L1) Ensure 'Deny log on as a service' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyServiceLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.24" + Task = "(L1) Ensure 'Deny log on locally' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.25" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' to include 'Guests' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.26" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' is set to 'Guests, Local account' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.27" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.28" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'No One' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.29" + Task = "(L1) Ensure 'Force shutdown from a remote system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if ($null -eq (Get-Module -Name ADFS)) { +[AuditTest] @{ + Id = "2.2.30 A" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE' [ADFS-ROLE NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +} +else{ +[AuditTest] @{ + Id = "2.2.30 B" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE' [ADFS-ROLE installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-80-1321940109-3370001082-3650459431-215109509-2472514016" + "S-1-5-80-2246541699-21809830-3603976364-117610243-975697593" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.31" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if ((Get-WindowsFeature -Name web-server).installed -ne $true) { +[AuditTest] @{ + Id = "2.2.32 A" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE' [IIS Role NOT installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +} +else { +[AuditTest] @{ + Id = "2.2.32 B" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE, IIS_IUSRS' [IIS Role installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-32-568" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.33" + Task = "(L1) Ensure 'Increase scheduling priority' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseBasePriorityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseBasePriorityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseBasePriorityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.34" + Task = "(L1) Ensure 'Load and unload device drivers' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.35" + Task = "(L1) Ensure 'Lock pages in memory' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.36" + Task = "(L2) Ensure 'Log on as a batch job' is set to 'Administrators' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBatchLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.37" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators' and (when Exchange is running in the environment) 'Exchange Servers' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.38" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.39" + Task = "(L1) Ensure 'Modify an object label' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRelabelPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRelabelPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRelabelPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.40" + Task = "(L1) Ensure 'Modify firmware environment values' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.41" + Task = "(L1) Ensure 'Perform volume maintenance tasks' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.42" + Task = "(L1) Ensure 'Profile single process' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.43" + Task = "(L1) Ensure 'Profile system performance' is set to 'Administrators, NT SERVICE\WdiServiceHost'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemProfilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemProfilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemProfilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.44" + Task = "(L1) Ensure 'Replace a process level token' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAssignPrimaryTokenPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAssignPrimaryTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAssignPrimaryTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.45" + Task = "(L1) Ensure 'Restore files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.46" + Task = "(L1) Ensure 'Shut down the system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.47" + Task = "(L1) Ensure 'Synchronize directory service data' is set to 'No One' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSyncAgentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSyncAgentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSyncAgentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.48" + Task = "(L1) Ensure 'Take ownership of files or other objects' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-DISA-V2R19#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-DISA-V2R19#AccountPolicies.ps1 new file mode 100644 index 0000000..f69b0b9 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-DISA-V2R19#AccountPolicies.ps1 @@ -0,0 +1,252 @@ +[AuditTest] @{ + Id = "V-1097" + Task = "The number of allowed bad logon attempts must meet minimum requirements." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 3 -or $setPolicy -eq 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x >= 3 and x != 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1098" + Task = "The reset period for the account lockout counter must be configured to 15 minutes or greater on Windows 2012." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1099" + Task = "Windows 2012 account lockout duration must be configured to 15 minutes or greater." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15) -and ($setPolicy -ne 0)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15 or x == 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1104" + Task = "The maximum password age must meet requirements." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 60 -or $setPolicy -eq 0)) { + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 60 and x != 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1105" + Task = "The minimum password age must meet requirements." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -eq 0)) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x != 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1107" + Task = "The password history must be configured to 24 passwords remembered." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1150" + Task = "The built-in Windows password complexity policy must be enabled." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-2372" + Task = "Reversible password encryption must be disabled." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-6836" + Task = "Passwords must, at a minimum, be 14 characters." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-DISA-V2R19#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-DISA-V2R19#AuditPolicies.ps1 new file mode 100644 index 0000000..b4363b3 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-DISA-V2R19#AuditPolicies.ps1 @@ -0,0 +1,1217 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "V-26529 + V-26530" + Task = "The system must be configured to audit Account Logon - Credential Validation successes. The system must be configured to audit Account Logon - Credential Validation failures." + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26533" + Task = "The system must be configured to audit Account Management - Other Account Management Events successes." + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26535" + Task = "The system must be configured to audit Account Management - Security Group Management successes." + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26537 + V-26538" + Task = "The system must be configured to audit Account Management - User Account Management successes. The system must be configured to audit Account Management - User Account Management failures." + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26539" + Task = "The system must be configured to audit Detailed Tracking - Process Creation successes." + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26540" + Task = "The system must be configured to audit Logon/Logoff - Logoff successes." + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26541 + V-26542" + Task = "The system must be configured to audit Logon/Logoff - Logon successes. The system must be configured to audit Logon/Logoff - Logon failures." + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26543" + Task = "The system must be configured to audit Logon/Logoff - Special Logon successes." + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26546 + V-26547" + Task = "The system must be configured to audit Policy Change - Audit Policy Change successes. The system must be configured to audit Policy Change - Audit Policy Change failures." + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26548" + Task = "The system must be configured to audit Policy Change - Authentication Policy Change successes." + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26549 + V-26550" + Task = "The system must be configured to audit Privilege Use - Sensitive Privilege Use successes. The system must be configured to audit Privilege Use - Sensitive Privilege Use failures." + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26551 + V-26552" + Task = "The system must be configured to audit System - IPsec Driver successes. The system must be configured to audit System - IPsec Driver failures." + Test = { + # Get the audit policy for the subcategory IPsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "IPsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'IPsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26553" + Task = "The system must be configured to audit System - Security State Change successes." + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26555" + Task = "The system must be configured to audit System - Security System Extension successes." + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-26557 + V-26558" + Task = "The system must be configured to audit System - System Integrity successes. The system must be configured to audit System - System Integrity failures." + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-36667 + V-36668" + Task = "The system must be configured to audit Object Access - Removable Storage failures. The system must be configured to audit Object Access - Removable Storage successes." + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-40200 + V-40202" + Task = "The system must be configured to audit Object Access - Central Access Policy Staging failures. The system must be configured to audit Object Access - Central Access Policy Staging successes." + Test = { + # Get the audit policy for the subcategory Central Policy Staging + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Central Policy Staging" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Central Policy Staging'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-57633" + Task = "The system must be configured to audit Policy Change - Authorization Policy Change successes." + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-78057 + V-78059" + Task = "Windows Server 2012/2012 R2 must be configured to audit Logon/Logoff - Account Lockout successes. Windows Server 2012/2012 R2 must be configured to audit Logon/Logoff - Account Lockout failures." + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-78061 + V-78063" + Task = "Windows Server 2012/2012 R2 must be configured to audit System - Other System Events successes. Windows Server 2012/2012 R2 must be configured to audit System - Other System Events failures." + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-DISA-V2R19#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-DISA-V2R19#RegistrySettings.ps1 new file mode 100644 index 0000000..f7cb7c0 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2012 R2-DISA-V2R19#RegistrySettings.ps1 @@ -0,0 +1,6330 @@ +[AuditTest] @{ + Id = "V-1075" + Task = "The shutdown option must not be available from the logon dialog box." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ShutdownWithoutLogon" ` + | Select-Object -ExpandProperty "ShutdownWithoutLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1089" + Task = "The required legal notice must be configured to display before console logon." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + if ($regValue -ne "See message text below") { + return @{ + Message = "Registry value is '$regValue'. Expected: See message text below" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1093" + Task = "Anonymous enumeration of shares must be restricted." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1136" + Task = "Users must be forcibly disconnected when their logon hours expire." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableForcedLogoff" ` + | Select-Object -ExpandProperty "EnableForcedLogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1141" + Task = "Unencrypted passwords must not be sent to third-party SMB Servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1145" + Task = "Automatic logons must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1151" + Task = "The print driver installation privilege must be restricted to administrators." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1153" + Task = "The LanMan authentication level must be set to send NTLMv2 response only, and to refuse LM and NTLM." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1154" + Task = "The Ctrl+Alt+Del security attention sequence for logons must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1162" + Task = "The Windows SMB server must perform SMB packet signing when possible." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-1163" + Task = "Outgoing secure channel traffic must be encrypted when possible." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1164" + Task = "Outgoing secure channel traffic must be signed when possible." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1165" + Task = "The computer account password must not be prevented from being reset." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1166" + Task = "The Windows SMB client must be enabled to perform SMB packet signing when possible." + Test = { + try { + if((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-1171" + Task = "Ejection of removable NTFS media must be restricted to Administrators." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AllocateDASD" ` + | Select-Object -ExpandProperty "AllocateDASD" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1172" + Task = "Users must be warned in advance of their passwords expiring." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if (($regValue -lt 14)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 14" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1173" + Task = "The default permissions of global system objects must be increased." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-1174" + Task = "The amount of idle time required before suspending a session must be properly set." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "autodisconnect" ` + | Select-Object -ExpandProperty "autodisconnect" + + if (($regValue -gt 15)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-11806" + Task = "The system must be configured to prevent the display of the last username on the logon screen." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14228" + Task = "Auditing the Access of Global System Objects must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "AuditBaseObjects" ` + | Select-Object -ExpandProperty "AuditBaseObjects" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14230" + Task = "Audit policy using subcategories must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14232" + Task = "IPSec Exemptions must be limited." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\IPSEC" ` + -Name "NoDefaultExempt" ` + | Select-Object -ExpandProperty "NoDefaultExempt" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14234" + Task = "User Account Control approval mode for the built-in Administrator must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14236" + Task = "User Account Control must automatically deny standard user requests for elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14237" + Task = "User Account Control must be configured to detect application installations and prompt for elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14239" + Task = "User Account Control must only elevate UIAccess applications that are installed in secure locations." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14240" + Task = "User Account Control must run all administrators in Admin Approval Mode, enabling UAC." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14241" + Task = "User Account Control must switch to the secure desktop when prompting for elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14242" + Task = "User Account Control must virtualize file and registry write failures to per-user locations." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14243" + Task = "Administrator accounts must not be enumerated during elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14247" + Task = "Passwords must not be saved in the Remote Desktop Client." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14249" + Task = "Local drives must be prevented from sharing with Remote Desktop Session Hosts. (Remote Desktop Services Role)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14253" + Task = "Unauthenticated RPC clients must be restricted from connecting to the RPC server." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14259" + Task = "Printing over HTTP must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14260" + Task = "Downloading print driver packages over HTTP must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14261" + Task = "Windows must be prevented from using Windows Update to search for drivers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DriverSearching" ` + -Name "DontSearchWindowsUpdate" ` + | Select-Object -ExpandProperty "DontSearchWindowsUpdate" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14268" + Task = "Zone information must be preserved when saving attachments." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14269" + Task = "Mechanisms for removing zone information from file attachments must be hidden." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "HideZoneInfoOnProperties" ` + | Select-Object -ExpandProperty "HideZoneInfoOnProperties" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-14270" + Task = "The system must notify antivirus when file attachments are opened." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "ScanWithAntiVirus" ` + | Select-Object -ExpandProperty "ScanWithAntiVirus" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15666" + Task = "Windows Peer-to-Peer networking services must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Peernet" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15667" + Task = "Network Bridges must be prohibited in Windows." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15672" + Task = "Event Viewer Events.asp links must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\EventViewer" ` + -Name "MicrosoftEventVwrDisableLinks" ` + | Select-Object -ExpandProperty "MicrosoftEventVwrDisableLinks" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15674" + Task = "The Internet File Association service must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInternetOpenWith" ` + | Select-Object -ExpandProperty "NoInternetOpenWith" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15682" + Task = "Attachments must be prevented from being downloaded from RSS feeds." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15683" + Task = "File Explorer shell protocol must run in protected mode." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15684" + Task = "Users must be notified if a web-based program attempts to install software." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15685" + Task = "Users must be prevented from changing installation options." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15686" + Task = "Nonadministrators must be prevented from applying vendor-signed updates." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "DisableLUAPatching" ` + | Select-Object -ExpandProperty "DisableLUAPatching" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15687" + Task = "Users must not be presented with Privacy and Installation options on first use of Windows Media Player." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsMediaPlayer" ` + -Name "GroupPrivacyAcceptance" ` + | Select-Object -ExpandProperty "GroupPrivacyAcceptance" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15699" + Task = "The Windows Connect Now wizards must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\UI" ` + -Name "DisableWcnUi" ` + | Select-Object -ExpandProperty "DisableWcnUi" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15700" + Task = "Remote access to the Plug and Play interface must be disabled for device installation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Settings" ` + -Name "AllowRemoteRPC" ` + | Select-Object -ExpandProperty "AllowRemoteRPC" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15701" + Task = "A system restore point must be created when a new device driver is installed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Settings" ` + -Name "DisableSystemRestore" ` + | Select-Object -ExpandProperty "DisableSystemRestore" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15702" + Task = "An Error Report must not be sent when a generic device driver is installed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Settings" ` + -Name "DisableSendGenericDriverNotFoundToWER" ` + | Select-Object -ExpandProperty "DisableSendGenericDriverNotFoundToWER" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15703" + Task = "Users must not be prompted to search Windows Update for device drivers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DriverSearching" ` + -Name "DontPromptForWindowsUpdate" ` + | Select-Object -ExpandProperty "DontPromptForWindowsUpdate" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15704" + Task = "Errors in handwriting recognition on tablet PCs must not be reported to Microsoft." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HandwritingErrorReports" ` + -Name "PreventHandwritingErrorReports" ` + | Select-Object -ExpandProperty "PreventHandwritingErrorReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15705" + Task = "Users must be prompted to authenticate on resume from sleep (on battery)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15706" + Task = "The user must be prompted to authenticate on resume from sleep (plugged in)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15707" + Task = "Remote Assistance log files must be generated." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "LoggingEnabled" ` + | Select-Object -ExpandProperty "LoggingEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15718" + Task = "Turning off File Explorer heap termination on corruption must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15722" + Task = "Windows Media Digital Rights Management (DRM) must be prevented from accessing the Internet." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WMDRM" ` + -Name "DisableOnline" ` + | Select-Object -ExpandProperty "DisableOnline" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15727" + Task = "Users must be prevented from sharing files in their profiles." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInPlaceSharing" ` + | Select-Object -ExpandProperty "NoInPlaceSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15991" + Task = "UIAccess applications must not be allowed to prompt for elevation without using the secure desktop." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableUIADesktopToggle" ` + | Select-Object -ExpandProperty "EnableUIADesktopToggle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15997" + Task = "Users must be prevented from mapping local COM ports and redirecting data from the Remote Desktop Session Host to local COM ports. (Remote Desktop Services Role)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCcm" ` + | Select-Object -ExpandProperty "fDisableCcm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15998" + Task = "Users must be prevented from mapping local LPT ports and redirecting data from the Remote Desktop Session Host to local LPT ports. (Remote Desktop Services Role)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLPT" ` + | Select-Object -ExpandProperty "fDisableLPT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-15999" + Task = "Users must be prevented from redirecting Plug and Play devices to the Remote Desktop Session Host. (Remote Desktop Services Role)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisablePNPRedir" ` + | Select-Object -ExpandProperty "fDisablePNPRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-16000" + Task = "The system must be configured to ensure smart card devices can be redirected to the Remote Desktop session. (Remote Desktop Services Role)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEnableSmartCard" ` + | Select-Object -ExpandProperty "fEnableSmartCard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-16008" + Task = "Windows must elevate all applications in User Account Control, not just signed ones." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ValidateAdminCodeSignatures" ` + | Select-Object -ExpandProperty "ValidateAdminCodeSignatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-16020" + Task = "The Windows Customer Experience Improvement Program must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SQMClient\Windows" ` + -Name "CEIPEnable" ` + | Select-Object -ExpandProperty "CEIPEnable" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-16021" + Task = "The Windows Help Experience Improvement Program must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Assistance\Client\1.0" ` + -Name "NoImplicitFeedback" ` + | Select-Object -ExpandProperty "NoImplicitFeedback" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-16048" + Task = "Windows Help Ratings feedback must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Assistance\Client\1.0" ` + -Name "NoExplicitFeedback" ` + | Select-Object -ExpandProperty "NoExplicitFeedback" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21950" + Task = "The service principal name (SPN) target name validation level must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SmbServerNameHardeningLevel" ` + | Select-Object -ExpandProperty "SmbServerNameHardeningLevel" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21951" + Task = "Services using Local System that use Negotiate when reverting to NTLM authentication must use the computer identity vs. authenticating anonymously." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\LSA" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21952" + Task = "NTLM must be prevented from falling back to a Null session." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\LSA\MSV1_0" ` + -Name "allownullsessionfallback" ` + | Select-Object -ExpandProperty "allownullsessionfallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21953" + Task = "PKU2U authentication using online identities must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\LSA\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21954" + Task = "Kerberos encryption types must be configured to prevent the use of DES and RC4 encryption suites." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21955" + Task = "IPv6 source routing must be configured to the highest protection level." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21956" + Task = "IPv6 TCP data retransmissions must be configured to prevent resources from becoming exhausted." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "TcpMaxDataRetransmissions" ` + | Select-Object -ExpandProperty "TcpMaxDataRetransmissions" + + if (($regValue -gt 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21960" + Task = "Domain users must be required to elevate when setting a networks location." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_StdDomainUserSetLocation" ` + | Select-Object -ExpandProperty "NC_StdDomainUserSetLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21961" + Task = "All Direct Access traffic must be routed through the internal network." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TCPIP\v6Transition" ` + -Name "Force_Tunneling" ` + | Select-Object -ExpandProperty "Force_Tunneling" + + if ($regValue -ne "Enabled") { + return @{ + Message = "Registry value is '$regValue'. Expected: Enabled" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21963" + Task = "Windows Update must be prevented from searching for point and print drivers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DoNotInstallCompatibleDriverFromWindowsUpdate" ` + | Select-Object -ExpandProperty "DoNotInstallCompatibleDriverFromWindowsUpdate" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21964" + Task = "Device metadata retrieval from the Internet must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" ` + -Name "PreventDeviceMetadataFromNetwork" ` + | Select-Object -ExpandProperty "PreventDeviceMetadataFromNetwork" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21965" + Task = "Device driver searches using Windows Update must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DriverSearching" ` + -Name "SearchOrderConfig" ` + | Select-Object -ExpandProperty "SearchOrderConfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21967" + Task = "Microsoft Support Diagnostic Tool (MSDT) interactive communication with Microsoft must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21969" + Task = "Access to Windows Online Troubleshooting Service (WOTS) must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "EnableQueryRemoteServer" ` + | Select-Object -ExpandProperty "EnableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21970" + Task = "Responsiveness events must be prevented from being aggregated and sent to Microsoft." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d}" ` + -Name "ScenarioExecutionEnabled" ` + | Select-Object -ExpandProperty "ScenarioExecutionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21971" + Task = "The Application Compatibility Program Inventory must be prevented from collecting data and sending the information to Microsoft." + Test = { + try { + $status = get-service -name pcasvc -ErrorAction Stop + if($status.Status -ne "Stopped"){ + return @{ + Message = "Compliant - AppCompat Service is disabled (no inventory data will be collected)." + Status = "True" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppCompat" ` + -Name "DisableInventory" ` + | Select-Object -ExpandProperty "DisableInventory" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + catch [System.SystemException]{ + return @{ + Message = "Service not found!" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21973" + Task = "Autoplay must be turned off for non-volume devices." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-21980" + Task = "Explorer Data Execution Prevention must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-22692" + Task = "The default Autorun behavior must be configured to prevent Autorun commands." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-2374" + Task = "Autoplay must be disabled for all drives." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-26283" + Task = "Anonymous enumeration of SAM accounts must not be allowed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-26359" + Task = "The Windows dialog box title for the legal banner must be configured." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + if ($regValue -ne "See message title options below") { + return @{ + Message = "Registry value is '$regValue'. Expected: See message title options below" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-26575" + Task = "The 6to4 IPv6 transition technology must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TCPIP\v6Transition" ` + -Name "6to4_State" ` + | Select-Object -ExpandProperty "6to4_State" + + if ($regValue -ne "Disabled") { + return @{ + Message = "Registry value is '$regValue'. Expected: Disabled" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-26576" + Task = "The IP-HTTPS IPv6 transition technology must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TCPIP\v6Transition\IPHTTPS\IPHTTPSInterface" ` + -Name "IPHTTPS_ClientState" ` + | Select-Object -ExpandProperty "IPHTTPS_ClientState" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-26577" + Task = "The ISATAP IPv6 transition technology must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TCPIP\v6Transition" ` + -Name "ISATAP_State" ` + | Select-Object -ExpandProperty "ISATAP_State" + + if ($regValue -ne "Disabled") { + return @{ + Message = "Registry value is '$regValue'. Expected: Disabled" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-26578" + Task = "The Teredo IPv6 transition technology must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TCPIP\v6Transition" ` + -Name "Teredo_State" ` + | Select-Object -ExpandProperty "Teredo_State" + + if ($regValue -ne "Disabled") { + return @{ + Message = "Registry value is '$regValue'. Expected: Disabled" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-26579" + Task = "The Application event log size must be configured to 32768 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-26580" + Task = "The Security event log size must be configured to 196608 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 196608)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-26581" + Task = "The Setup event log size must be configured to 32768 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-26582" + Task = "The System event log size must be configured to 32768 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-28504" + Task = "Windows must be prevented from sending an error report when a device driver requests additional software during installation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DeviceInstall\Settings" ` + -Name "DisableSendRequestAdditionalSoftwareToWER" ` + | Select-Object -ExpandProperty "DisableSendRequestAdditionalSoftwareToWER" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3343" + Task = "Solicited Remote Assistance must not be allowed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3344" + Task = "Local accounts with blank passwords must be restricted to prevent access from the network." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3373" + Task = "The maximum age for machine account passwords must be set to requirements." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if (($regValue -gt 30 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3374" + Task = "The system must be configured to require a strong session key." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3377" + Task = "The system must be configured to prevent anonymous users from having the same rights as the Everyone group." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3378" + Task = "The system must be configured to use the Classic security model." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3379" + Task = "The system must be configured to prevent the storage of the LAN Manager hash of passwords." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3381" + Task = "The system must be configured to the required LDAP client signing level." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3382" + Task = "The system must be configured to meet the minimum session security requirement for NTLM SSP-based clients." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3383" + Task = "The system must be configured to use FIPS-compliant algorithms for encryption, hashing, and signing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3385" + Task = "The system must be configured to require case insensitivity for non-Windows subsystems." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3449" + Task = "Remote Desktop Services must limit users to one remote session." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fSingleSessionPerUser " ` + | Select-Object -ExpandProperty "fSingleSessionPerUser " + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3453" + Task = "Remote Desktop Services must always prompt a client for passwords upon connection." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3454" + Task = "Remote Desktop Services must be configured with the client connection encryption set to the required level." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3455" + Task = "Remote Desktop Services must be configured to use session-specific temporary folders." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "PerSessionTempDir" ` + | Select-Object -ExpandProperty "PerSessionTempDir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3456" + Task = "Remote Desktop Services must delete temporary folders when a session is terminated." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3470" + Task = "The system must be configured to prevent unsolicited remote assistance offers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3479" + Task = "The system must be configured to use Safe DLL Search Mode." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3480" + Task = "Windows Media Player must be configured to prevent automatic checking for updates." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsMediaPlayer" ` + -Name "DisableAutoupdate" ` + | Select-Object -ExpandProperty "DisableAutoupdate" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3481" + Task = "Media Player must be configured to prevent automatic Codec downloads." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\WindowsMediaPlayer" ` + -Name "PreventCodecDownload" ` + | Select-Object -ExpandProperty "PreventCodecDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-34974" + Task = "The Windows Installer Always install with elevated privileges option must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36439" + Task = "Local administrator accounts must have their privileged token filtered to prevent elevated privileges from being used over the network on domain systems." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36656" + Task = "A screen saver must be enabled on the system." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaveActive" ` + | Select-Object -ExpandProperty "ScreenSaveActive" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36657" + Task = "The screen saver must be password protected." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Control Panel\Desktop" ` + -Name "ScreenSaverIsSecure" ` + | Select-Object -ExpandProperty "ScreenSaverIsSecure" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-3666" + Task = "The system must be configured to meet the minimum session security requirement for NTLM SSP-based servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36673" + Task = "IP stateless autoconfiguration limits state must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableIPAutoConfigurationLimits" ` + | Select-Object -ExpandProperty "EnableIPAutoConfigurationLimits" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36677" + Task = "Optional component installation and component repair must be prevented from using Windows Update." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Servicing" ` + -Name "UseWindowsUpdate" ` + | Select-Object -ExpandProperty "UseWindowsUpdate" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36678" + Task = "Device driver updates must only search managed servers, not Windows Update." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DriverSearching" ` + -Name "DriverServerSelection" ` + | Select-Object -ExpandProperty "DriverServerSelection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36679" + Task = "Early Launch Antimalware, Boot-Start Driver Initialization Policy must be enabled and configured to only Good and Unknown." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36680" + Task = "Access to the Windows Store must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoUseStoreOpenWith" ` + | Select-Object -ExpandProperty "NoUseStoreOpenWith" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36681" + Task = "Copying of user input methods to the system account for sign-in must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Control Panel\International" ` + -Name "BlockUserInputMethodsForSignIn" ` + | Select-Object -ExpandProperty "BlockUserInputMethodsForSignIn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36684" + Task = "Local users on domain-joined computers must not be enumerated." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36687" + Task = "App notifications on the lock screen must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36696" + Task = "The detection of compatibility issues for applications and drivers must be turned off." + Test = { + try { + $status = get-service -name pcasvc -ErrorAction Stop + if($status.Status -ne "Stopped"){ + return @{ + Message = "Compliant - AppCompat Service is disabled (no inventory data will be collected)." + Status = "True" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AppCompat" ` + -Name "DisablePcaUI" ` + | Select-Object -ExpandProperty "DisablePcaUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + catch [System.SystemException]{ + return @{ + Message = "Service not found!" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36697" + Task = "Trusted app installation must be enabled to allow for signed enterprise line of business apps." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Appx" ` + -Name "AllowAllTrustedApps" ` + | Select-Object -ExpandProperty "AllowAllTrustedApps" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36698" + Task = "The use of biometrics must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36700" + Task = "The password reveal button must not be displayed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36709" + Task = "Basic authentication for RSS feeds over HTTP must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "AllowBasicAuthInClear" ` + | Select-Object -ExpandProperty "AllowBasicAuthInClear" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36710" + Task = "Automatic download of updates from the Windows Store must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "AutoDownload" ` + | Select-Object -ExpandProperty "AutoDownload" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36711" + Task = "The Windows Store application must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore" ` + -Name "RemoveWindowsStore" ` + | Select-Object -ExpandProperty "RemoveWindowsStore" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36712" + Task = "The Windows Remote Management (WinRM) client must not use Basic authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36713" + Task = "The Windows Remote Management (WinRM) client must not allow unencrypted traffic." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36714" + Task = "The Windows Remote Management (WinRM) client must not use Digest authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36718" + Task = "The Windows Remote Management (WinRM) service must not use Basic authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36719" + Task = "The Windows Remote Management (WinRM) service must not allow unencrypted traffic." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36720" + Task = "The Windows Remote Management (WinRM) service must not store RunAs credentials." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36773" + Task = "The machine inactivity limit must be set to 15 minutes, locking the system with the screensaver." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36776" + Task = "Notifications from Windows Push Network Service must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-36777" + Task = "Toast notifications to the lock screen must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-40204" + Task = "Only the default client printer must be redirected to the Remote Desktop Session Host. (Remote Desktop Services Role)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "RedirectOnlyDefaultClientPrinter" ` + | Select-Object -ExpandProperty "RedirectOnlyDefaultClientPrinter" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-4108" + Task = "The system must generate an audit event when the audit log reaches a percentage of full threshold." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Eventlog\Security" ` + -Name "WarningLevel" ` + | Select-Object -ExpandProperty "WarningLevel" + + if (($regValue -gt 90)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 90" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-4110" + Task = "The system must be configured to prevent IP source routing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-4111" + Task = "The system must be configured to prevent Internet Control Message Protocol (ICMP) redirects from overriding Open Shortest Path First (OSPF) generated routes." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-4112" + Task = "The system must be configured to disable the Internet Router Discovery Protocol (IRDP)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "PerformRouterDiscovery" ` + | Select-Object -ExpandProperty "PerformRouterDiscovery" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-4113" + Task = "The system must be configured to limit how often keep-alive packets are sent." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "KeepAliveTime" ` + | Select-Object -ExpandProperty "KeepAliveTime" + + if (($regValue -gt 300000)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 300000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-4116" + Task = "The system must be configured to ignore NetBIOS name release requests except from WINS servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NoNameReleaseOnDemand" ` + | Select-Object -ExpandProperty "NoNameReleaseOnDemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-43238" + Task = "The display of slide shows on the lock screen must be disabled (Windows 2012 R2)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-43239" + Task = "Windows 2012 R2 must include command line data in process creation events." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-43240" + Task = "The network selection user interface (UI) must not be displayed on the logon screen (Windows 2012 R2)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-43241" + Task = "The setting to allow Microsoft accounts to be optional for modern style apps must be enabled (Windows 2012 R2)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-43245" + Task = "Automatically signing in the last interactive user after a system-initiated restart must be disabled (Windows 2012 R2)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-4438" + Task = "The system must limit how many times unacknowledged TCP data is retransmitted." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "TcpMaxDataRetransmissions" ` + | Select-Object -ExpandProperty "TcpMaxDataRetransmissions" + + if (($regValue -gt 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-4447" + Task = "The Remote Desktop Session Host must require secure RPC communications." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-4448" + Task = "Group Policy objects must be reprocessed even if they have not changed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-57639" + Task = "Users must be required to enter a password to access private keys stored on the computer." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography" ` + -Name "ForceKeyProtection" ` + | Select-Object -ExpandProperty "ForceKeyProtection" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-6831" + Task = "Outgoing secure channel traffic must be encrypted or signed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-6832" + Task = "The Windows SMB client must be configured to always perform SMB packet signing." + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-6833" + Task = "The Windows SMB server must be configured to always perform SMB packet signing." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-6834" + Task = "Anonymous access to Named Pipes and Shares must be restricted." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-72753" + Task = "WDigest Authentication must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Wdigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73519" + Task = "The Server Message Block (SMB) v1 protocol must be disabled on the SMB server." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73523" + Task = "The Server Message Block (SMB) v1 protocol must be disabled on the SMB client." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-80475" + Task = "PowerShell script block logging must be enabled on Windows 2012/2012 R2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#AccountPolicies.ps1 new file mode 100644 index 0000000..422bbfd --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#AccountPolicies.ps1 @@ -0,0 +1,283 @@ +[AuditTest] @{ + Id = "1.1.1" + Task = "(L1) Ensure 'Enforce password history' is set to '24 or more password(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "(L1) Ensure 'Maximum password age' is set to '365 or fewer days, but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 365 -or $setPolicy -le 0)) { + if($setPolicy -eq -1){ #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 365 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "(L1) Ensure 'Minimum password age' is set to '1 or more day(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 1)) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "(L1) Ensure 'Minimum password length' is set to '14 or more character(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.5" + Task = "(L1) Ensure 'Password must meet complexity requirements' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.6" + Task = "(L1) Ensure 'Store passwords using reversible encryption' is set to 'Disabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "(L1) Ensure 'Account lockout duration' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -lt 15) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "(L1) Ensure 'Account lockout threshold' is set to '5 or fewer invalid logon attempt(s), but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 5 -or $setPolicy -le 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 5 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.3" + Task = "(L1) Ensure 'Allow Administrator account lockout' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["AllowAdministratorLockout"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'AllowAdministratorLockout' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.4" + Task = "(L1) Ensure 'Reset account lockout counter after' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -lt 15) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#AuditPolicies.ps1 new file mode 100644 index 0000000..da2f9f0 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#AuditPolicies.ps1 @@ -0,0 +1,2036 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "17.1.1" + Task = "(L1) Ensure 'Audit Credential Validation' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.1.2" + Task = "(L1) Ensure 'Audit Kerberos Authentication Service' is set to 'Success and Failure' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Kerberos Authentication Service + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kerberos Authentication Service" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kerberos Authentication Service'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.1.3" + Task = "(L1) Ensure 'Audit Kerberos Service Ticket Operations' is set to 'Success and Failure' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Kerberos Service Ticket Operations + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kerberos Service Ticket Operations" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kerberos Service Ticket Operations'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.1" + Task = "(L1) Ensure 'Audit Application Group Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Application Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Application Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Application Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.2" + Task = "(L1) Ensure 'Audit Computer Account Management' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Computer Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Computer Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Computer Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.3" + Task = "(L1) Ensure 'Audit Distribution Group Management' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Distribution Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Distribution Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Distribution Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.4" + Task = "(L1) Ensure 'Audit Other Account Management Events' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.5" + Task = "(L1) Ensure 'Audit Security Group Management' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.6" + Task = "(L1) Ensure 'Audit User Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.1" + Task = "(L1) Ensure 'Audit PNP Activity' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.2" + Task = "(L1) Ensure 'Audit Process Creation' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.4.1" + Task = "(L1) Ensure 'Audit Directory Service Access' is set to include 'Failure' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Directory Service Access + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Access" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Access'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.4.2" + Task = "(L1) Ensure 'Audit Directory Service Changes' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Directory Service Changes + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Changes" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Changes'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.1" + Task = "(L1) Ensure 'Audit Account Lockout' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.2" + Task = "(L1) Ensure 'Audit Group Membership' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.3" + Task = "(L1) Ensure 'Audit Logoff' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.4" + Task = "(L1) Ensure 'Audit Logon' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.5" + Task = "(L1) Ensure 'Audit Other Logon/Logoff Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.6" + Task = "(L1) Ensure 'Audit Special Logon' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.1" + Task = "(L1) Ensure 'Audit Detailed File Share' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.2" + Task = "(L1) Ensure 'Audit File Share' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.3" + Task = "(L1) Ensure 'Audit Other Object Access Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.4" + Task = "(L1) Ensure 'Audit Removable Storage' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.1" + Task = "(L1) Ensure 'Audit Audit Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.2" + Task = "(L1) Ensure 'Audit Authentication Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.3" + Task = "(L1) Ensure 'Audit Authorization Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.4" + Task = "(L1) Ensure 'Audit MPSSVC Rule-Level Policy Change' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Mpssvc Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Mpssvc Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Mpssvc Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.5" + Task = "(L1) Ensure 'Audit Other Policy Change Events' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.8.1" + Task = "(L1) Ensure 'Audit Sensitive Privilege Use' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.1" + Task = "(L1) Ensure 'Audit IPsec Driver' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Ipsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Ipsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Ipsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.2" + Task = "(L1) Ensure 'Audit Other System Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.3" + Task = "(L1) Ensure 'Audit Security State Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.4" + Task = "(L1) Ensure 'Audit Security System Extension' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.5" + Task = "(L1) Ensure 'Audit System Integrity' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#RegistrySettings.ps1 new file mode 100644 index 0000000..1c8d782 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#RegistrySettings.ps1 @@ -0,0 +1,12380 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$avstatus = CheckForActiveAV +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "2.3.1.1" + Task = "(L1) Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "NoConnectedUser" ` + | Select-Object -ExpandProperty "NoConnectedUser" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.3" + Task = "(L1) Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.1" + Task = "(L1) Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.2" + Task = "(L1) Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "CrashOnAuditFail" ` + | Select-Object -ExpandProperty "CrashOnAuditFail" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4.1" + Task = "(L1) Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.1" + Task = "(L1) Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SubmitControl" ` + | Select-Object -ExpandProperty "SubmitControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.2" + Task = "(L1) Ensure 'Domain controller: Allow vulnerable Netlogon secure channel connections' is set to 'Not Configured' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "vulnerablechannelallowlist" ` + | Select-Object -ExpandProperty "vulnerablechannelallowlist" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.3" + Task = "(L1) Ensure 'Domain controller: LDAP server channel binding token requirements' is set to 'Always' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LdapEnforceChannelBinding" ` + | Select-Object -ExpandProperty "LdapEnforceChannelBinding" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.4" + Task = "(L1) Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LDAPServerIntegrity" ` + | Select-Object -ExpandProperty "LDAPServerIntegrity" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.5" + Task = "(L1) Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RefusePasswordChange" ` + | Select-Object -ExpandProperty "RefusePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.1" + Task = "(L1) Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.2" + Task = "(L1) Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.3" + Task = "(L1) Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.4" + Task = "(L1) Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.5" + Task = "(L1) Ensure 'Domain member: Maximum machine account password age' is set to '30 or fewer days, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if ($regValue -le 0 -or $regValue -gt 30) { + return @{ + Message = "Registry value is '$regValue'. Expected: x > 0 and x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.6" + Task = "(L1) Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.1" + Task = "(L1) Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.2" + Task = "(L1) Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.3" + Task = "(L1) Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if ($regValue -gt 900 -or $regValue -eq 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.4" + Task = "(L1) Configure 'Interactive logon: Message text for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.5" + Task = "(L1) Configure 'Interactive logon: Message title for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.6" + Task = "(L2) Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "CachedLogonsCount" ` + | Select-Object -ExpandProperty "CachedLogonsCount" + + if ($regValue -notmatch "^[43210]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[43210]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.7" + Task = "(L1) Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if ($regValue -gt 14 -or $regValue -lt 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 14 and x >= 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.8" + Task = "(L1) Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ForceUnlockLogon" ` + | Select-Object -ExpandProperty "ForceUnlockLogon" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.9" + Task = "(L1) Ensure 'Interactive logon: Smart card removal behavior' is set to 1 - 'Lock Workstation' or 2 / 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -notmatch "^(1|2|3)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(1|2|3)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.8.1" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.2" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.3" + Task = "(L1) Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.1" + Task = "(L1) Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if ($regValue -gt 15) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.2" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.3" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.4" + Task = "(L1) Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "enableforcedlogoff" ` + | Select-Object -ExpandProperty "enableforcedlogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.5" + Task = "(L1) Ensure 'Microsoft network server: Server SPN target name validation level' is set to 1 - 'Accept if provided by client' or 2 - higher (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "SMBServerNameHardeningLevel" ` + | Select-Object -ExpandProperty "SMBServerNameHardeningLevel" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.2" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.3" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.4" + Task = "(L2) Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.5" + Task = "(L1) Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.6" + Task = "(L1) Configure 'Network access: Named Pipes that can be accessed anonymously' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + $reference = @( + "LSARPC" + "NETLOGON" + "SAMR" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: LSARPC NETLOGON SAMR" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.7" + Task = "(L1) Configure 'Network access: Named Pipes that can be accessed anonymously' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.8" + Task = "(L1) Configure 'Network access: Remotely accessible registry paths'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\ProductOptions" + "System\CurrentControlSet\Control\Server Applications" + "Software\Microsoft\Windows NT\CurrentVersion" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\ProductOptions System\CurrentControlSet\Control\Server Applications Software\Microsoft\Windows NT\CurrentVersion" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +$CARoleStatus = (Get-WindowsFeature -Name ADCS-Cert-Authority).Installed +$WINSStatus = (Get-WindowsFeature -Name WINS).Installed +[AuditTest] @{ + Id = "2.3.10.9 A" + Task = "(L1) Configure 'Network access: Remotely accessible registry paths and sub-paths' [WINS Role Feature and CA Role Service NOT installed]" + Test = { + try { + if (($CARoleStatus -or $WINSStatus) -eq $true){ + return @{ + Message = "WINS Role Feature or CA Role Service are installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9 B" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured [CA Role Service installed]" + Test = { + try { + if ($CARoleStatus -eq $false){ + return @{ + Message = "CA Role Service NOT installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + "System\CurrentControlSet\Services\CertSvc" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog System\CurrentControlSet\Services\CertSvc" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9 C" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured [WINS Role Feature installed]" + Test = { + try { + if ($WINSStatus -eq $false){ + return @{ + Message = "WINS Role Feature NOT installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + "System\CurrentControlSet\Services\WINS" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog System\CurrentControlSet\Services\WINS" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.10" + Task = "(L1) Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.11" + Task = "(L1) Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "restrictremotesam" ` + | Select-Object -ExpandProperty "restrictremotesam" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.12" + Task = "(L1) Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionShares" ` + | Select-Object -ExpandProperty "NullSessionShares" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.13" + Task = "(L1) Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.1" + Task = "(L1) Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.2" + Task = "(L1) Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.3" + Task = "(L1) Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.4" + Task = "(L1) Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.5" + Task = "(L1) Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.7" + Task = "(L1) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.8" + Task = "(L1) Ensure 'Network security: LDAP client signing requirements' is set to 1 - 'Negotiate signing' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1 -and $regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.9" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.10" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.11" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Audit Incoming NTLM Traffic' is set to 'Enable auditing for all accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AuditReceivingNTLMTraffic" ` + | Select-Object -ExpandProperty "AuditReceivingNTLMTraffic" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.12" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Audit NTLM authentication in this domain' is set to 'Enable all' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "AuditNTLMInDomain" ` + | Select-Object -ExpandProperty "AuditNTLMInDomain" + + if ($regValue -ne 7) { + return @{ + Message = "Registry value is '$regValue'. Expected: 7" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.13" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers' is set to 1 - 'Audit all' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "RestrictSendingNTLMTraffic" ` + | Select-Object -ExpandProperty "RestrictSendingNTLMTraffic" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.13.1" + Task = "(L1) Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ShutdownWithoutLogon" ` + | Select-Object -ExpandProperty "ShutdownWithoutLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.1" + Task = "(L1) Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.2" + Task = "(L1) Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.1" + Task = "(L1) Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.2" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 2 - 'Prompt for consent on the secure desktop' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.3" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.4" + Task = "(L1) Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.5" + Task = "(L1) Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.6" + Task = "(L1) Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.7" + Task = "(L1) Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.8" + Task = "(L1) Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1" + Task = "(L1) Ensure 'Print Spooler (Spooler)' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2" + Task = "(L2) Ensure 'Print Spooler (Spooler)' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.1.1" + Task = "(L1) Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.2" + Task = "(L1) Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.3" + Task = "(L1) Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.4" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\domainfw.log'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\domainfw.log"; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.5" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.6" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.7" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.1" + Task = "(L1) Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.2" + Task = "(L1) Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.3" + Task = "(L1) Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.4" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\privatefw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\privatefw.log"; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.5" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.6" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.7" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.1" + Task = "(L1) Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.2" + Task = "(L1) Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.3" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.4" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.5" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.6" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\publicfw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\publicfw.log"; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.7" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.8" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.9" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "18.1.1.1" + Task = "(L1) Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.1.2" + Task = "(L1) Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.2.2" + Task = "(L1) Ensure 'Allow users to enable online speech recognition services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "AllowInputPersonalization" ` + | Select-Object -ExpandProperty "AllowInputPersonalization" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.3" + Task = "(L2) Ensure 'Allow Online Tips' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "AllowOnlineTips" ` + | Select-Object -ExpandProperty "AllowOnlineTips" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.2" + Task = "(L1) Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "PwdExpirationProtectionEnabled" ` + | Select-Object -ExpandProperty "PwdExpirationProtectionEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.3" + Task = "(L1) Ensure 'Enable Local Admin Password Management' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft Services\AdmPwd" ` + -Name "AdmPwdEnabled" ` + | Select-Object -ExpandProperty "AdmPwdEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.4" + Task = "(L1) Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "PasswordComplexity" ` + | Select-Object -ExpandProperty "PasswordComplexity" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.5" + Task = "(L1) Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "PasswordLength" ` + | Select-Object -ExpandProperty "PasswordLength" + + if ($regValue -lt 15) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.6" + Task = "(L1) Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd" ` + -Name "PasswordAgeDays" ` + | Select-Object -ExpandProperty "PasswordAgeDays" + + if ($regValue -gt 30) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.1" + Task = "(L1) Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.2" + Task = "(L1) Ensure 'Configure RPC packet level privacy setting for incoming connections' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print" ` + -Name "RpcAuthnLevelPrivacyEnabled" ` + | Select-Object -ExpandProperty "RpcAuthnLevelPrivacyEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.3" + Task = "(L1) Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.4" + Task = "(L1) Ensure 'Configure SMB v1 server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.5" + Task = "(L1) Ensure 'Enable Certificate Padding' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Wintrust\Config" ` + -Name "EnableCertPaddingCheck" ` + | Select-Object -ExpandProperty "EnableCertPaddingCheck" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.6" + Task = "(L1) Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.7" + Task = "(L1) Ensure 'LSA Protection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RunAsPPL" ` + | Select-Object -ExpandProperty "RunAsPPL" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.8" + Task = "(L1) Ensure 'NetBT NodeType configuration' is set to 'Enabled: P-node (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.9" + Task = "(L1) Ensure 'WDigest Authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.1" + Task = "(L1) Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.2" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.3" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.4" + Task = "(L1) Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.5" + Task = "(L2) Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "KeepAliveTime" ` + | Select-Object -ExpandProperty "KeepAliveTime" + + if ($regValue -ne 300000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 300000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.6" + Task = "(L1) Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.7" + Task = "(L2) Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "PerformRouterDiscovery" ` + | Select-Object -ExpandProperty "PerformRouterDiscovery" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.8" + Task = "(L1) Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.9" + Task = "(L1) Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScreenSaverGracePeriod" ` + | Select-Object -ExpandProperty "ScreenSaverGracePeriod" + + if ($regValue -notmatch "^[0-5]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[0-5]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.10" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.11" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.12" + Task = "(L1) Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security" ` + -Name "WarningLevel" ` + | Select-Object -ExpandProperty "WarningLevel" + + if ($regValue -gt 90) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 90" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.1" + Task = "(L1) Ensure 'Configure NetBIOS settings' is set to 2 - 'Enabled: Disable NetBIOS name resolution on public networks' (or 0 - Disable NetBIOS name resolution)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableNetBIOS" ` + | Select-Object -ExpandProperty "EnableNetBIOS" + + if (($regValue -ne 2) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2 or 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.2" + Task = "(L1) Ensure 'Turn off multicast name resolution' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.5.1" + Task = "(L2) Ensure 'Enable Font Providers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableFontProviders" ` + | Select-Object -ExpandProperty "EnableFontProviders" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.1" + Task = "(L1) Ensure 'Enable insecure guest logons' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 A" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnDomain" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 B" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnPublicNet" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 C" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (EnableLLTDIO)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableLLTDIO" ` + | Select-Object -ExpandProperty "EnableLLTDIO" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 D" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitLLTDIOOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitLLTDIOOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 A" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnDomain" ` + | Select-Object -ExpandProperty "AllowRspndrOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 B" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnPublicNet" ` + | Select-Object -ExpandProperty "AllowRspndrOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 C" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (EnableRspndr)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableRspndr" ` + | Select-Object -ExpandProperty "EnableRspndr" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 D" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitRspndrOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitRspndrOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.10.2" + Task = "(L2) Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Peernet" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.2" + Task = "(L1) Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.3" + Task = "(L1) Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.4" + Task = "(L1) Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_StdDomainUserSetLocation" ` + | Select-Object -ExpandProperty "NC_StdDomainUserSetLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 A" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares' (\\*\NETLOGON)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "RequirePrivacy=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 B" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares' (\\*\SYSVOL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "RequirePrivacy=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.19.2.1" + Task = "(L2) Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "DisabledComponents" ` + | Select-Object -ExpandProperty "DisabledComponents" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 A" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (EnableRegistrars)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "EnableRegistrars" ` + | Select-Object -ExpandProperty "EnableRegistrars" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 B" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableUPnPRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableUPnPRegistrar" ` + | Select-Object -ExpandProperty "DisableUPnPRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 C" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableInBand802DOT11Registrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableInBand802DOT11Registrar" ` + | Select-Object -ExpandProperty "DisableInBand802DOT11Registrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 D" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableFlashConfigRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableFlashConfigRegistrar" ` + | Select-Object -ExpandProperty "DisableFlashConfigRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 E" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableWPDRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableWPDRegistrar" ` + | Select-Object -ExpandProperty "DisableWPDRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.2" + Task = "(L2) Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\UI" ` + -Name "DisableWcnUi" ` + | Select-Object -ExpandProperty "DisableWcnUi" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.1" + Task = "(L1) Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled: 1 = Minimize simultaneous connections'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fMinimizeConnections" ` + | Select-Object -ExpandProperty "fMinimizeConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.2" + Task = "(L2) Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.1" + Task = "(L1) Ensure 'Allow Print Spooler to accept client connections' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "RegisterSpoolerRemoteRpcEndPoint" ` + | Select-Object -ExpandProperty "RegisterSpoolerRemoteRpcEndPoint" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.2" + Task = "(L1) Ensure 'Configure Redirection Guard' is set to 'Enabled: Redirection Guard Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "RedirectionGuardPolicy" ` + | Select-Object -ExpandProperty "RedirectionGuardPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.3" + Task = "(L1) Ensure 'Configure RPC connection settings: Protocol to use for outgoing RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcUseNamedPipeProtocol" ` + | Select-Object -ExpandProperty "RpcUseNamedPipeProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.4" + Task = "(L1) Ensure 'Configure RPC connection settings: Use authentication for outgoing RPC connections' is set to 'Enabled: Default'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcAuthentication" ` + | Select-Object -ExpandProperty "RpcAuthentication" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.5" + Task = "(L1) Ensure 'Configure RPC listener settings: Protocols to allow for incoming RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcProtocols" ` + | Select-Object -ExpandProperty "RpcProtocols" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.6" + Task = "(L1) Ensure 'Configure RPC listener settings: Authentication protocol to use for incoming RPC connections:' is set to 'Enabled: 0 - Negotiate' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "ForceKerberosForRpc" ` + | Select-Object -ExpandProperty "ForceKerberosForRpc" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0 or 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.7" + Task = "(L1) Ensure 'Configure RPC over TCP port' is set to 'Enabled: 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcTcpPort" ` + | Select-Object -ExpandProperty "RpcTcpPort" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.8" + Task = "(L1) Ensure 'Limits print driver installation to Administrators' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "RestrictDriverInstallationToAdministrators" ` + | Select-Object -ExpandProperty "RestrictDriverInstallationToAdministrators" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.9" + Task = "(L1) Ensure 'Manage processing of Queue-specific files' is set to 'Enabled: Limit Queue-specific files to Color profiles'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "CopyFilesPolicy" ` + | Select-Object -ExpandProperty "CopyFilesPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.10" + Task = "(L1) Ensure 'Point and Print Restrictions: When installing drivers for a new connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "NoWarningNoElevationOnInstall" ` + | Select-Object -ExpandProperty "NoWarningNoElevationOnInstall" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.11" + Task = "(L1) Ensure 'Point and Print Restrictions: When updating drivers for an existing connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "UpdatePromptSettings" ` + | Select-Object -ExpandProperty "UpdatePromptSettings" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.1.1" + Task = "(L2) Ensure 'Turn off notifications network usage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.3.1" + Task = "(L1) Ensure 'Include command line in process creation events' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.1" + Task = "(L1) Ensure 'Encryption Oracle Remediation' is set to 'Enabled: Force Updated Clients'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.2" + Task = "(L1) Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.1" + Task = "(NG) Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.2" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Select Platform Security Level' is set to 1 - 'Secure Boot' or 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if (($regValue -ne 1) -and ($regValue -ne 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.3" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Virtualization Based Protection of Code Integrity' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.4" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Require UEFI Memory Attributes Table' is set to 'True (checked)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HVCIMATRequired" ` + | Select-Object -ExpandProperty "HVCIMATRequired" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.5" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Enabled with UEFI lock' (MS Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.6" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Disabled' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.7" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Secure Launch Configuration' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureSystemGuardLaunch" ` + | Select-Object -ExpandProperty "ConfigureSystemGuardLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.2" + Task = "(L1) Ensure 'Prevent device metadata retrieval from the Internet' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" ` + -Name "PreventDeviceMetadataFromNetwork" ` + | Select-Object -ExpandProperty "PreventDeviceMetadataFromNetwork" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.13.1" + Task = "(L1) Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.2" + Task = "(L1) Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.3" + Task = "(L1) Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.4" + Task = "(L1) Ensure 'Configure security policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.5" + Task = "(L1) Ensure 'Configure security policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.6" + Task = "(L1) Ensure 'Continue experiences on this device' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableCdp" ` + | Select-Object -ExpandProperty "EnableCdp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.7" + Task = "(L1) Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableBkGndGroupPolicy" ` + | Select-Object -ExpandProperty "DisableBkGndGroupPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.1" + Task = "(L1) Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.2" + Task = "(L2) Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TabletPC" ` + -Name "PreventHandwritingDataSharing" ` + | Select-Object -ExpandProperty "PreventHandwritingDataSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.3" + Task = "(L2) Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HandwritingErrorReports" ` + -Name "PreventHandwritingErrorReports" ` + | Select-Object -ExpandProperty "PreventHandwritingErrorReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.4" + Task = "(L2) Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Internet Connection Wizard" ` + -Name "ExitOnMSICW" ` + | Select-Object -ExpandProperty "ExitOnMSICW" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.5" + Task = "(L1) Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.6" + Task = "(L2) Ensure 'Turn off printing over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.7" + Task = "(L2) Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Registration Wizard Control" ` + -Name "NoRegistration" ` + | Select-Object -ExpandProperty "NoRegistration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.8" + Task = "(L2) Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SearchCompanion" ` + -Name "DisableContentFileUpdates" ` + | Select-Object -ExpandProperty "DisableContentFileUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.9" + Task = "(L2) Ensure 'Turn off the `"Order Prints`" picture task' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoOnlinePrintsWizard" ` + | Select-Object -ExpandProperty "NoOnlinePrintsWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.10" + Task = "(L2) Ensure 'Turn off the `"Publish to Web`" task for files and folders' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoPublishingWizard" ` + | Select-Object -ExpandProperty "NoPublishingWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.11" + Task = "(L2) Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Messenger\Client" ` + -Name "CEIP" ` + | Select-Object -ExpandProperty "CEIP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.12" + Task = "(L2) Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SQMClient\Windows" ` + -Name "CEIPEnable" ` + | Select-Object -ExpandProperty "CEIPEnable" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13 A" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (Disabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13 B" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (DoReport)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\PCHealth\ErrorReporting" ` + -Name "DoReport" ` + | Select-Object -ExpandProperty "DoReport" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 A" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitBehavior)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitBehavior" ` + | Select-Object -ExpandProperty "DevicePKInitBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 B" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitEnabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitEnabled" ` + | Select-Object -ExpandProperty "DevicePKInitEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.1" + Task = "(L2) Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Control Panel\International" ` + -Name "BlockUserInputMethodsForSignIn" ` + | Select-Object -ExpandProperty "BlockUserInputMethodsForSignIn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.1" + Task = "(L1) Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockUserFromShowingAccountDetailsOnSignin" ` + | Select-Object -ExpandProperty "BlockUserFromShowingAccountDetailsOnSignin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.2" + Task = "(L1) Ensure 'Do not display network selection UI' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.3" + Task = "(L1) Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontEnumerateConnectedUsers" ` + | Select-Object -ExpandProperty "DontEnumerateConnectedUsers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.4" + Task = "(L1) Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.5" + Task = "(L1) Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.6" + Task = "(L1) Ensure 'Turn off picture password sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "BlockDomainPicturePassword" ` + | Select-Object -ExpandProperty "BlockDomainPicturePassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.7" + Task = "(L1) Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.1" + Task = "(L2) Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.2" + Task = "(L2) Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.3" + Task = "(L1) Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.4" + Task = "(L1) Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.1" + Task = "(L1) Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.2" + Task = "(L1) Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.36.1" + Task = "(L1) Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "EnableAuthEpResolution" ` + | Select-Object -ExpandProperty "EnableAuthEpResolution" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.36.2" + Task = "(L2) Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1" + Task = "(L2) Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.11.1" + Task = "(L2) Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d}" ` + -Name "ScenarioExecutionEnabled" ` + | Select-Object -ExpandProperty "ScenarioExecutionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.49.1" + Task = "(L2) Ensure 'Turn off the advertising ID' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" ` + -Name "DisabledByGroupPolicy" ` + | Select-Object -ExpandProperty "DisabledByGroupPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.51.1.1" + Task = "(L1) Ensure 'Enable Windows NTP Client' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.51.1.2" + Task = "(L1) Ensure 'Enable Windows NTP Server' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.3.1" + Task = "(L2) Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager" ` + -Name "AllowSharedLocalAppData" ` + | Select-Object -ExpandProperty "AllowSharedLocalAppData" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.5.1" + Task = "(L1) Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.1" + Task = "(L1) Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.2" + Task = "(L1) Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.3" + Task = "(L1) Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.8.1.1" + Task = "(L1) Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1" + Task = "(L2) Ensure 'Allow Use of Camera' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera" ` + -Name "AllowCamera" ` + | Select-Object -ExpandProperty "AllowCamera" + + if ($regValue -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam" ` + -Name "Value" ` + | Select-Object -ExpandProperty "Value" + + if ($regValue -match "Deny") { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Camera is not deactivated." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "18.10.12.1" + Task = "(L1) Ensure 'Turn off cloud consumer account state content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableConsumerAccountStateContent" ` + | Select-Object -ExpandProperty "DisableConsumerAccountStateContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.12.2" + Task = "(L1) Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.13.1" + Task = "(L1) Ensure 'Require pin for pairing' is set to 'Enabled: First Time' OR 'Enabled: Always'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect" ` + -Name "RequirePinForPairing" ` + | Select-Object -ExpandProperty "RequirePinForPairing" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.1" + Task = "(L1) Ensure 'Do not display the password reveal button' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.2" + Task = "(L1) Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.1" + Task = "(L1) Ensure 'Allow Diagnostic Data' is set to '0 - Enabled: Diagnostic data off (not recommended)' or '1 - Enabled: Send required diagnostic data'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0 or 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.2" + Task = "(L2) Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableEnterpriseAuthProxy" ` + | Select-Object -ExpandProperty "DisableEnterpriseAuthProxy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.3" + Task = "(L1) Ensure 'Disable OneSettings Downloads' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableOneSettingsDownloads" ` + | Select-Object -ExpandProperty "DisableOneSettingsDownloads" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.4" + Task = "(L1) Ensure 'Do not show feedback notifications' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DoNotShowFeedbackNotifications" ` + | Select-Object -ExpandProperty "DoNotShowFeedbackNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.5" + Task = "(L1) Ensure 'Enable OneSettings Auditing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "EnableOneSettingsAuditing" ` + | Select-Object -ExpandProperty "EnableOneSettingsAuditing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.6" + Task = "(L1) Ensure 'Limit Diagnostic Log Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDiagnosticLogCollection" ` + | Select-Object -ExpandProperty "LimitDiagnosticLogCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.7" + Task = "(L1) Ensure 'Limit Dump Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDumpCollection" ` + | Select-Object -ExpandProperty "LimitDumpCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.8" + Task = "(L1) Ensure 'Toggle user control over Insider builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" ` + -Name "AllowBuildPreview" ` + | Select-Object -ExpandProperty "AllowBuildPreview" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.1.1" + Task = "(L1) Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.1.2" + Task = "(L1) Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.2.1" + Task = "(L1) Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.2.2" + Task = "(L1) Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.3.1" + Task = "(L1) Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.3.2" + Task = "(L1) Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.4.1" + Task = "(L1) Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.4.2" + Task = "(L1) Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.28.2" + Task = "(L1) Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.28.3" + Task = "(L1) Ensure 'Turn off heap termination on corruption' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.28.4" + Task = "(L1) Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.36.1" + Task = "(L2) Ensure 'Turn off location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.40.1" + Task = "(L2) Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging" ` + -Name "AllowMessageSync" ` + | Select-Object -ExpandProperty "AllowMessageSync" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.41.1" + Task = "(L1) Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount" ` + -Name "DisableUserAuth" ` + | Select-Object -ExpandProperty "DisableUserAuth" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.5.1" + Task = "(L1) Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.5.2" + Task = "(L2) Ensure 'Join Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.1" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 A" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office communication application from creating child processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 B" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating executable content'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 C" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block abuse of exploited vulnerable signed drivers'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 D" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block execution of potentially obfuscated scripts'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 E" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from injecting code into other processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 F" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Adobe Reader from creating child processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 G" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block credential stealing from the Windows local security authority subsystem (lsass.exe)'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 H" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block untrusted and unsigned processes that run from USB'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 I" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block executable content from email client and webmail'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 J" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating child processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.3.1" + Task = "(L1) Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.7.1" + Task = "(L1) Ensure 'Enable file hash computation feature' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\MpEngine" ` + -Name "EnableFileHashComputation" ` + | Select-Object -ExpandProperty "EnableFileHashComputation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.1" + Task = "(L1) Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.2" + Task = "(L1) Ensure 'Turn off real-time protection' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.3" + Task = "(L1) Ensure 'Turn on behavior monitoring' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.4" + Task = "(L1) Ensure 'Turn on script scanning' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableScriptScanning" ` + | Select-Object -ExpandProperty "DisableScriptScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.12.1" + Task = "(L2) Ensure 'Configure Watson events' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" ` + -Name "DisableGenericReports" ` + | Select-Object -ExpandProperty "DisableGenericReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.13.1" + Task = "(L1) Ensure 'Scan packed executables' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisablePackedExeScanning" ` + | Select-Object -ExpandProperty "DisablePackedExeScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.13.2" + Task = "(L1) Ensure 'Scan removable drives' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.13.3" + Task = "(L1) Ensure 'Turn on e-mail scanning' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.16" + Task = "(L1) Ensure 'Configure detection for potentially unwanted applications' is set to 'Enabled: Block'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.17" + Task = "(L1) Ensure 'Turn off Microsoft Defender AntiVirus' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "DisableAntiSpyware" ` + | Select-Object -ExpandProperty "DisableAntiSpyware" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.50.1" + Task = "(L1) Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.55.1" + Task = "(L2) Ensure 'Turn off Push To Install service' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall" ` + -Name "DisablePushToInstall" ` + | Select-Object -ExpandProperty "DisablePushToInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.2.2" + Task = "(L1) Ensure 'Do not allow passwords to be saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.2.1" + Task = "(L2) Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fSingleSessionPerUser" ` + | Select-Object -ExpandProperty "fSingleSessionPerUser" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.1" + Task = "(L2) Ensure 'Do not allow COM port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCcm" ` + | Select-Object -ExpandProperty "fDisableCcm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.2" + Task = "(L1) Ensure 'Do not allow drive redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.3" + Task = "(L2) Ensure 'Do not allow LPT port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLPT" ` + | Select-Object -ExpandProperty "fDisableLPT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.4" + Task = "(L2) Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisablePNPRedir" ` + | Select-Object -ExpandProperty "fDisablePNPRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.1" + Task = "(L1) Ensure 'Always prompt for password upon connection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.2" + Task = "(L1) Ensure 'Require secure RPC communication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.3" + Task = "(L1) Ensure 'Require use of specific security layer for remote (RDP) connections' is set to 'Enabled: SSL'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SecurityLayer" ` + | Select-Object -ExpandProperty "SecurityLayer" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.4" + Task = "(L1) Ensure 'Require user authentication for remote connections by using Network Level Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "UserAuthentication" ` + | Select-Object -ExpandProperty "UserAuthentication" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.5" + Task = "(L1) Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.10.1" + Task = "(L2) Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less, but not Never (0)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxIdleTime" ` + | Select-Object -ExpandProperty "MaxIdleTime" + + if ($regValue -gt 900000 -or $regValue -eq 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900000 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.10.2" + Task = "(L2) Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxDisconnectionTime" ` + | Select-Object -ExpandProperty "MaxDisconnectionTime" + + if ($regValue -ne 60000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 60000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.11.1" + Task = "(L1) Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.11.2" + Task = "(L1) Ensure 'Do not use temporary folders per session' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "PerSessionTempDir" ` + | Select-Object -ExpandProperty "PerSessionTempDir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.1" + Task = "(L1) Ensure 'Prevent downloading of enclosures' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.2" + Task = "(L2) Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCloudSearch" ` + | Select-Object -ExpandProperty "AllowCloudSearch" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.3" + Task = "(L1) Ensure 'Allow indexing of encrypted files' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.4" + Task = "(L2) Ensure 'Allow search highlights' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "EnableDynamicContentInWSB" ` + | Select-Object -ExpandProperty "EnableDynamicContentInWSB" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.62.1" + Task = "(L2) Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" ` + -Name "NoGenTicket" ` + | Select-Object -ExpandProperty "NoGenTicket" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.75.2.1 A" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (EnableSmartScreen)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.75.2.1 B" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (ShellSmartScreenLevel)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.79.1" + Task = "(L2) Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowSuggestedAppsInWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowSuggestedAppsInWindowsInkWorkspace" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.79.2" + Task = "(L1) Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Enabled: Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if (($regValue -ne 1) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.1" + Task = "(L1) Ensure 'Allow user control over installs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.2" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.3" + Task = "(L2) Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.1" + Task = "(L1) Ensure 'Sign-in and lock last interactive user automatically after a restart' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.86.1" + Task = "(L2) Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.86.2" + Task = "(L2) Ensure 'Turn on PowerShell Transcription' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" ` + -Name "EnableTranscripting" ` + | Select-Object -ExpandProperty "EnableTranscripting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.1.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.1.2" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.1.3" + Task = "(L1) Ensure 'Disallow Digest authentication' is set to 'Enabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.2" + Task = "(L2) Ensure 'Allow remote server management through WinRM' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowAutoConfig" ` + | Select-Object -ExpandProperty "AllowAutoConfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.3" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.4" + Task = "(L1) Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1" + Task = "(L2) Ensure 'Allow Remote Shell Access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service\WinRS" ` + -Name "AllowRemoteShellAccess" ` + | Select-Object -ExpandProperty "AllowRemoteShellAccess" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.91.2.1" + Task = "(L1) Ensure 'Prevent users from modifying settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection" ` + -Name "DisallowExploitProtectionOverride" ` + | Select-Object -ExpandProperty "DisallowExploitProtectionOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.1.1" + Task = "(L1) Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.1" + Task = "(L1) Ensure 'Configure Automatic Updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.2" + Task = "(L1) Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.1" + Task = "(L1) Ensure 'Manage preview builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "ManagePreviewBuildsPolicyValue" ` + | Select-Object -ExpandProperty "ManagePreviewBuildsPolicyValue" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.2 A" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdates" ` + | Select-Object -ExpandProperty "DeferFeatureUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.2 B" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferFeatureUpdatesPeriodInDays" + + if ($regValue -lt 180 -or $regValue -gt 365) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 180 and x <= 365" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.3 A" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdates" ` + | Select-Object -ExpandProperty "DeferQualityUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.3 B" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferQualityUpdatesPeriodInDays" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.5.1.1" + Task = "(L1) Ensure 'Turn off toast notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.6.6.1.1" + Task = "(L2) Ensure 'Turn off Help Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Assistance\Client\1.0" ` + -Name "NoImplicitFeedback" ` + | Select-Object -ExpandProperty "NoImplicitFeedback" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.5.1" + Task = "(L1) Ensure 'Do not preserve zone information in file attachments' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.5.2" + Task = "(L1) Ensure 'Notify antivirus programs when opening attachments' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "ScanWithAntiVirus" ` + | Select-Object -ExpandProperty "ScanWithAntiVirus" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.1" + Task = "(L1) Ensure 'Configure Windows spotlight on lock screen' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "ConfigureWindowsSpotlight" ` + | Select-Object -ExpandProperty "ConfigureWindowsSpotlight" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.2" + Task = "(L1) Ensure 'Do not suggest third-party content in Windows spotlight' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.3" + Task = "(L2) Ensure 'Do not use diagnostic data for tailored experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableTailoredExperiencesWithDiagnosticData" ` + | Select-Object -ExpandProperty "DisableTailoredExperiencesWithDiagnosticData" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.4" + Task = "(L2) Ensure 'Turn off all Windows spotlight features' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsSpotlightFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsSpotlightFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.5" + Task = "(L1) Ensure 'Turn off Spotlight collection on Desktop' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableSpotlightCollectionOnDesktop" ` + | Select-Object -ExpandProperty "DisableSpotlightCollectionOnDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.26.1" + Task = "(L1) Ensure 'Prevent users from sharing files within their profile.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInplaceSharing" ` + | Select-Object -ExpandProperty "NoInplaceSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.42.1" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled' (AlwaysInstallElevated)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.44.2.1" + Task = "(L2) Ensure 'Prevent Codec Download' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\WindowsMediaPlayer" ` + -Name "PreventCodecDownload" ` + | Select-Object -ExpandProperty "PreventCodecDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#SecurityOptions.ps1 new file mode 100644 index 0000000..59b8d27 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#SecurityOptions.ps1 @@ -0,0 +1,133 @@ +[AuditTest] @{ + Id = "2.3.1.2" + Task = "(L1) Ensure 'Accounts: Guest account status' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.4" + Task = "(L1) Configure 'Accounts: Rename administrator account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption. Expected: ^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.5" + Task = "(L1) Configure 'Accounts: Rename guest account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption. Expected: ^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.1" + Task = "(L1) Ensure 'Network access: Allow anonymous SID/Name translation' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.6" + Task = "(L1) Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["ForceLogoffWhenHourExpire"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 1) { + return @{ + Message = "'ForceLogoffWhenHourExpire' currently set to: $setOption. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#UserRights.ps1 new file mode 100644 index 0000000..94e1a2f --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-CIS-3.0.0#UserRights.ps1 @@ -0,0 +1,1984 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + if ($sidAccount.Translate([System.Security.Principal.NTAccount]) -eq "NULL SID") { + return @{ + Account = $null + Sid = $sidAccount.Value + } + } else { + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "2.2.1" + Task = "(L1) Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Authenticated Users, ENTERPRISE DOMAIN CONTROLLERS' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-11" + "S-1-5-32-544" + "S-1-5-9" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.3" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Authenticated Users' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-11" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.4" + Task = "(L1) Ensure 'Act as part of the operating system' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.5" + Task = "(L1) Ensure 'Add workstations to domain' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeMachineAccountPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeMachineAccountPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeMachineAccountPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.6" + Task = "(L1) Ensure 'Adjust memory quotas for a process' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseQuotaPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseQuotaPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseQuotaPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.7" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators, ENTERPRISE DOMAIN CONTROLLERS' (DC only)" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-9" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.8" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators' (MS only)" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.9" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.10" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators, Remote Desktop Users' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.11" + Task = "(L1) Ensure 'Back up files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.12" + Task = "(L1) Ensure 'Change the system time' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemtimePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemtimePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemtimePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.13" + Task = "(L1) Ensure 'Change the time zone' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTimeZonePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTimeZonePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTimeZonePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Ensure 'Create a pagefile' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.15" + Task = "(L1) Ensure 'Create a token object' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.16" + Task = "(L1) Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.17" + Task = "(L1) Ensure 'Create permanent shared objects' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.18" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if($hyperVStatus -ne "Enabled"){ +[AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators [Hyper-V-Feature NOT installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +} +else{ +[AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators, NT VIRTUAL MACHINE\Virtual Machines' [Hyper-V-Feature installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + if ($null -eq (Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V)) { + return @{ + Status = "None" + Message = "Hyper-V not installed." + } + } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.20" + Task = "(L1) Ensure 'Debug programs' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.21" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.22" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests, Local account and member of Administrators group' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-114" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.23" + Task = "(L1) Ensure 'Deny log on as a batch job' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.24" + Task = "(L1) Ensure 'Deny log on as a service' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyServiceLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.25" + Task = "(L1) Ensure 'Deny log on locally' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.26" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' to include 'Guests' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.27" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' is set to 'Guests, Local account' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.28" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.29" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'No One' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.30" + Task = "(L1) Ensure 'Force shutdown from a remote system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if ($null -eq (Get-Module -Name ADFS)) { +[AuditTest] @{ + Id = "2.2.31 A" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE' [ADFS-ROLE NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +} +else{ +[AuditTest] @{ + Id = "2.2.31 B" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE' [ADFS-ROLE installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-80-1321940109-3370001082-3650459431-215109509-2472514016" + "S-1-5-80-2246541699-21809830-3603976364-117610243-975697593" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.32" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if ((Get-WindowsFeature -Name web-server).installed -ne $true) { +[AuditTest] @{ + Id = "2.2.33 A" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE' [IIS Role NOT installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +} +else{ +[AuditTest] @{ + Id = "2.2.33 B" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE, IIS_IUSRS' [IIS Role installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-32-568" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.34" + Task = "(L1) Ensure 'Increase scheduling priority' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseBasePriorityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseBasePriorityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseBasePriorityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.35" + Task = "(L1) Ensure 'Load and unload device drivers' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.36" + Task = "(L1) Ensure 'Lock pages in memory' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.37" + Task = "(L2) Ensure 'Log on as a batch job' is set to 'Administrators' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBatchLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.38" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators' and (when Exchange is running in the environment) 'Exchange Servers' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.39" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.40" + Task = "(L1) Ensure 'Modify an object label' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRelabelPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRelabelPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRelabelPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.41" + Task = "(L1) Ensure 'Modify firmware environment values' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.42" + Task = "(L1) Ensure 'Perform volume maintenance tasks' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.43" + Task = "(L1) Ensure 'Profile single process' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.44" + Task = "(L1) Ensure 'Profile system performance' is set to 'Administrators, NT SERVICE\WdiServiceHost'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemProfilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemProfilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemProfilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.45" + Task = "(L1) Ensure 'Replace a process level token' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAssignPrimaryTokenPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAssignPrimaryTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAssignPrimaryTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.46" + Task = "(L1) Ensure 'Restore files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.47" + Task = "(L1) Ensure 'Shut down the system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.48" + Task = "(L1) Ensure 'Synchronize directory service data' is set to 'No One' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSyncAgentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSyncAgentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSyncAgentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.49" + Task = "(L1) Ensure 'Take ownership of files or other objects' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-1.12#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-1.12#UserRights.ps1 new file mode 100644 index 0000000..2af5d78 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-1.12#UserRights.ps1 @@ -0,0 +1,71 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#AccountPolicies.ps1 new file mode 100644 index 0000000..a500d49 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#AccountPolicies.ps1 @@ -0,0 +1,252 @@ +[AuditTest] @{ + Id = "V-73309" + Task = "Windows 2016 account lockout duration must be configured to 15 minutes or greater." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15) -and ($setPolicy -ne 0)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15 or x == 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73311" + Task = "Windows Server 2016 must have the number of allowed bad logon attempts configured to three or less." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 3 -or $setPolicy -eq 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x >= 3 and x != 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73313" + Task = "Windows Server 2016 must have the period of time before the bad logon counter is reset configured to 15 minutes or greater." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73315" + Task = "Windows Server 2016 password history must be configured to 24 passwords remembered." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73317" + Task = "Windows Server 2016 maximum password age must be configured to 60 days or less." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 60 -or $setPolicy -eq 0)) { + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 60 and x != 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73319" + Task = "Windows Server 2016 minimum password age must be configured to at least one day." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -eq 0)) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x != 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73321" + Task = "Windows Server 2016 minimum password length must be configured to 14 characters." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73323" + Task = "Windows Server 2016 must have the built-in Windows password complexity policy enabled." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73325" + Task = "Windows Server 2016 reversible password encryption must be disabled." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#AuditPolicies.ps1 new file mode 100644 index 0000000..52d25bf --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#AuditPolicies.ps1 @@ -0,0 +1,1502 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "V-73413 + V-73415" + Task = "Windows Server 2016 must be configured to audit Account Logon - Credential Validation successes. Windows Server 2016 must be configured to audit Account Logon - Credential Validation failures." + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73417" + Task = "Windows Server 2016 must be configured to audit Account Management - Computer Account Management successes." + Test = { + # Get the audit policy for the subcategory Computer Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Computer Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Computer Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73419" + Task = "Windows Server 2016 must be configured to audit Account Management - Other Account Management Events successes." + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73423" + Task = "Windows Server 2016 must be configured to audit Account Management - Security Group Management successes." + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73427 + V-73429" + Task = "Windows Server 2016 must be configured to audit Account Management - User Account Management successes. Windows Server 2016 must be configured to audit Account Management - User Account Management failures." + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73431" + Task = "Windows Server 2016 must be configured to audit Detailed Tracking - Plug and Play Events successes." + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73433" + Task = "Windows Server 2016 must be configured to audit Detailed Tracking - Process Creation successes." + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73435 + V-73437" + Task = "Windows Server 2016 must be configured to audit DS Access - Directory Service Access successes. Windows Server 2016 must be configured to audit DS Access - Directory Service Access failures." + Test = { + # Get the audit policy for the subcategory Directory Service Access + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Access" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Access'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73439 + V-73441" + Task = "Windows Server 2016 must be configured to audit DS Access - Directory Service Changes successes. Windows Server 2016 must be configured to audit DS Access - Directory Service Changes failures." + Test = { + # Get the audit policy for the subcategory Directory Service Changes + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Changes" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Changes'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73443 + V-73445" + Task = "Windows Server 2016 must be configured to audit Logon/Logoff - Account Lockout successes. Windows Server 2016 must be configured to audit Logon/Logoff - Account Lockout failures." + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73447" + Task = "Windows Server 2016 must be configured to audit Logon/Logoff - Group Membership successes." + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73449" + Task = "Windows Server 2016 must be configured to audit Logon/Logoff - Logoff successes." + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73451 + V-73453" + Task = "Windows Server 2016 must be configured to audit Logon/Logoff - Logon successes. Windows Server 2016 must be configured to audit Logon/Logoff - Logon failures." + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73455" + Task = "Windows Server 2016 must be configured to audit Logon/Logoff - Special Logon successes." + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73457 + V-73459" + Task = "Windows Server 2016 must be configured to audit Object Access - Removable Storage successes. Windows Server 2016 must be configured to audit Object Access - Removable Storage failures." + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73461 + V-73463" + Task = "Windows Server 2016 must be configured to audit Policy Change - Audit Policy Change successes. Windows Server 2016 must be configured to audit Policy Change - Audit Policy Change failures." + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73465" + Task = "Windows Server 2016 must be configured to audit Policy Change - Authentication Policy Change successes." + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73467" + Task = "Windows Server 2016 must be configured to audit Policy Change - Authorization Policy Change successes." + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73469 + V-73471" + Task = "Windows Server 2016 must be configured to audit Privilege Use - Sensitive Privilege Use successes. Windows Server 2016 must be configured to audit Privilege Use - Sensitive Privilege Use failures." + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73473 + V-73475" + Task = "Windows Server 2016 must be configured to audit System - IPsec Driver successes. Windows Server 2016 must be configured to audit System - IPsec Driver failures." + Test = { + # Get the audit policy for the subcategory IPsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "IPsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'IPsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73477 + V-73479" + Task = "Windows Server 2016 must be configured to audit System - Other System Events successes. Windows Server 2016 must be configured to audit System - Other System Events failures." + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73481" + Task = "Windows Server 2016 must be configured to audit System - Security State Change successes." + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73483" + Task = "Windows Server 2016 must be configured to audit System - Security System Extension successes." + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-73489 + V-73491" + Task = "Windows Server 2016 must be configured to audit System - System Integrity successes. Windows Server 2016 must be configured to audit System - System Integrity failures." + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-90359 + V-90361" + Task = "Windows 2016 must be configured to audit Object Access - Other Object Access Events successes. Windows 2016 must be configured to audit Object Access - Other Object Access Events failures." + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#RegistrySettings.ps1 new file mode 100644 index 0000000..db36dd7 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#RegistrySettings.ps1 @@ -0,0 +1,3437 @@ +[AuditTest] @{ + Id = "V-73487" + Task = "Administrator accounts must not be enumerated during elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73493" + Task = "The display of slide shows on the lock screen must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73495" + Task = "Local administrator accounts must have their privileged token filtered to prevent elevated privileges from being used over the network on domain systems." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73497" + Task = "WDigest Authentication must be disabled on Windows Server 2016." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Wdigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73499" + Task = "Internet Protocol version 6 (IPv6) source routing must be configured to the highest protection level to prevent IP source routing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73501" + Task = "Source routing must be configured to the highest protection level to prevent Internet Protocol (IP) source routing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73503" + Task = "Windows Server 2016 must be configured to prevent Internet Control Message Protocol (ICMP) redirects from overriding Open Shortest Path First (OSPF)-generated routes." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73505" + Task = "Windows Server 2016 must be configured to ignore NetBIOS name release requests except from WINS servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NoNameReleaseOnDemand" ` + | Select-Object -ExpandProperty "NoNameReleaseOnDemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73507" + Task = "Insecure logons to an SMB server must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73511" + Task = "Command line data must be included in process creation events." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73521" + Task = "Early Launch Antimalware, Boot-Start Driver Initialization Policy must prevent boot drivers identified as bad." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if (($regValue -ne 1) -and ($regValue -ne 3) -and ($regValue -ne 8)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 3 or x == 8" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73525" + Task = "Group Policy objects must be reprocessed even if they have not changed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73527" + Task = "Downloading print driver packages over HTTP must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73529" + Task = "Printing over HTTP must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73531" + Task = "The network selection user interface (UI) must not be displayed on the logon screen." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73533" + Task = "Local users on domain-joined computers must not be enumerated." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73537" + Task = "Users must be prompted to authenticate when the system wakes from sleep (on battery)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73539" + Task = "Users must be prompted to authenticate when the system wakes from sleep (plugged in)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73541" + Task = "Unauthenticated Remote Procedure Call (RPC) clients must be restricted from connecting to the RPC server." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73543" + Task = "The Application Compatibility Program Inventory must be prevented from collecting data and sending the information to Microsoft." + Test = { + try { + $status = get-service -name pcasvc -ErrorAction Stop + if($status.Status -ne "Stopped"){ + return @{ + Message = "Compliant - AppCompat Service is disabled (no inventory data will be collected)." + Status = "True" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppCompat" ` + -Name "DisableInventory" ` + | Select-Object -ExpandProperty "DisableInventory" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + catch [System.SystemException]{ + return @{ + Message = "Service not found!" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73545" + Task = "AutoPlay must be turned off for non-volume devices." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73547" + Task = "The default AutoRun behavior must be configured to prevent AutoRun commands." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73549" + Task = "AutoPlay must be disabled for all drives." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73553" + Task = "The Application event log size must be configured to 32768 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73555" + Task = "The Security event log size must be configured to 196608 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 196608)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73557" + Task = "The System event log size must be configured to 32768 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73559" + Task = "Windows Server 2016 Windows SmartScreen must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73561" + Task = "Explorer Data Execution Prevention must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73563" + Task = "Turning off File Explorer heap termination on corruption must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73565" + Task = "File Explorer shell protocol must run in protected mode." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73567" + Task = "Passwords must not be saved in the Remote Desktop Client." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73569" + Task = "Local drives must be prevented from sharing with Remote Desktop Session Hosts." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73571" + Task = "Remote Desktop Services must always prompt a client for passwords upon connection." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73573" + Task = "The Remote Desktop Session Host must require secure Remote Procedure Call (RPC) communications." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73575" + Task = "Remote Desktop Services must be configured with the client connection encryption set to High Level." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73577" + Task = "Attachments must be prevented from being downloaded from RSS feeds." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73579" + Task = "Basic authentication for RSS feeds over HTTP must not be used." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "AllowBasicAuthInClear" ` + | Select-Object -ExpandProperty "AllowBasicAuthInClear" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73581" + Task = "Indexing of encrypted files must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73583" + Task = "Users must be prevented from changing installation options." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73585" + Task = "The Windows Installer Always install with elevated privileges option must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73587" + Task = "Users must be notified if a web-based program attempts to install software." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73589" + Task = "Automatically signing in the last interactive user after a system-initiated restart must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73591" + Task = "PowerShell script block logging must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\ Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73593" + Task = "The Windows Remote Management (WinRM) client must not use Basic authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73595" + Task = "The Windows Remote Management (WinRM) client must not allow unencrypted traffic." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73597" + Task = "The Windows Remote Management (WinRM) client must not use Digest authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73599" + Task = "The Windows Remote Management (WinRM) service must not use Basic authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73601" + Task = "The Windows Remote Management (WinRM) service must not allow unencrypted traffic." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73603" + Task = "The Windows Remote Management (WinRM) service must not store RunAs credentials." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73621" + Task = "Local accounts with blank passwords must be restricted to prevent access from the network." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73627" + Task = "Audit policy using subcategories must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73629" + Task = "Domain controllers must require LDAP access signing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LDAPServerIntegrity" ` + | Select-Object -ExpandProperty "LDAPServerIntegrity" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73631" + Task = "Domain controllers must be configured to allow reset of machine account passwords." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RefusePasswordChange" ` + | Select-Object -ExpandProperty "RefusePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73633" + Task = "The setting Domain member: Digitally encrypt or sign secure channel data (always) must be configured to Enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73635" + Task = "The setting Domain member: Digitally encrypt secure channel data (when possible) must be configured to enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73637" + Task = "The setting Domain member: Digitally sign secure channel data (when possible) must be configured to Enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73639" + Task = "The computer account password must not be prevented from being reset." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73641" + Task = "The maximum age for machine account passwords must be configured to 30 days or less." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if (($regValue -gt 30 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73643" + Task = "Windows Server 2016 must be configured to require a strong session key." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73645" + Task = "The machine inactivity limit must be set to 15 minutes, locking the system with the screen saver." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73647" + Task = "The required legal notice must be configured to display before console logon." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + if ($regValue -ne "See message text below") { + return @{ + Message = "Registry value is '$regValue'. Expected: See message text below" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73649" + Task = "The Windows dialog box title for the legal banner must be configured with the appropriate text." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + if ($regValue -ne "See message title options below") { + return @{ + Message = "Registry value is '$regValue'. Expected: See message title options below" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73653" + Task = "The setting Microsoft network client: Digitally sign communications (always) must be configured to Enabled." + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-73655" + Task = "The setting Microsoft network client: Digitally sign communications (if server agrees) must be configured to Enabled." + Test = { + try { + if((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-73657" + Task = "Unencrypted passwords must not be sent to third-party Server Message Block (SMB) servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73661" + Task = "The setting Microsoft network server: Digitally sign communications (always) must be configured to Enabled." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-73663" + Task = "The setting Microsoft network server: Digitally sign communications (if client agrees) must be configured to Enabled." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-73667" + Task = "Anonymous enumeration of Security Account Manager (SAM) accounts must not be allowed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73669" + Task = "Anonymous enumeration of shares must not be allowed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73673" + Task = "Windows Server 2016 must be configured to prevent anonymous users from having the same permissions as the Everyone group." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73675" + Task = "Anonymous access to Named Pipes and Shares must be restricted." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73677" + Task = "Remote calls to the Security Account Manager (SAM) must be restricted to Administrators." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictRemoteSAM" ` + | Select-Object -ExpandProperty "RestrictRemoteSAM" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73679" + Task = "Services using Local System that use Negotiate when reverting to NTLM authentication must use the computer identity instead of authenticating anonymously." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73681" + Task = "NTLM must be prevented from falling back to a Null session." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA\MSV1_0" ` + -Name "allownullsessionfallback" ` + | Select-Object -ExpandProperty "allownullsessionfallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73683" + Task = "PKU2U authentication using online identities must be prevented." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73685" + Task = "Kerberos encryption types must be configured to prevent the use of DES and RC4 encryption suites." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73687" + Task = "Windows Server 2016 must be configured to prevent the storage of the LAN Manager hash of passwords." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73691" + Task = "The LAN Manager authentication level must be set to send NTLMv2 response only and to refuse LM and NTLM." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73693" + Task = "Windows Server 2016 must be configured to at least negotiate signing for LDAP client signing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73695" + Task = "Session security for NTLM SSP-based clients must be configured to require NTLMv2 session security and 128-bit encryption." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73697" + Task = "Session security for NTLM SSP-based servers must be configured to require NTLMv2 session security and 128-bit encryption." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73699" + Task = "Users must be required to enter a password to access private keys stored on the computer." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography" ` + -Name "ForceKeyProtection" ` + | Select-Object -ExpandProperty "ForceKeyProtection" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73701" + Task = "Windows Server 2016 must be configured to use FIPS-compliant algorithms for encryption, hashing, and signing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73705" + Task = "The default permissions of global system objects must be strengthened." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73707" + Task = "User Account Control approval mode for the built-in Administrator must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73709" + Task = "UIAccess applications must not be allowed to prompt for elevation without using the secure desktop." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableUIADesktopToggle" ` + | Select-Object -ExpandProperty "EnableUIADesktopToggle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73713" + Task = "User Account Control must automatically deny standard user requests for elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73715" + Task = "User Account Control must be configured to detect application installations and prompt for elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73717" + Task = "User Account Control must only elevate UIAccess applications that are installed in secure locations." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73719" + Task = "User Account Control must run all administrators in Admin Approval Mode, enabling UAC." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73721" + Task = "User Account Control must virtualize file and registry write failures to per-user locations." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73727" + Task = "Zone information must be preserved when saving attachments." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-78123" + Task = "The Server Message Block (SMB) v1 protocol must be disabled on the SMB server." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-78125" + Task = "The Server Message Block (SMB) v1 protocol must be disabled on the SMB client." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#SecurityOptions.ps1 new file mode 100644 index 0000000..0fb03a1 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-DISA-V1R12#SecurityOptions.ps1 @@ -0,0 +1,104 @@ +[AuditTest] @{ + Id = "V-73623" + Task = "Windows Server 2016 built-in administrator account must be renamed." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?!.*\bAdministrator\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73625" + Task = "Windows Server 2016 built-in guest account must be renamed." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73665" + Task = "Anonymous SID/Name translation must not be allowed." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-73809" + Task = "Windows Server 2016 built-in guest account must be disabled." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#AccountPolicies.ps1 new file mode 100644 index 0000000..dab2b4d --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#AccountPolicies.ps1 @@ -0,0 +1,252 @@ +[AuditTest] @{ + Id = "AccountPolicy-001" + Task = "Ensure 'MinimumPasswordAge' is set to '1'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-002" + Task = "Ensure 'MaximumPasswordAge' is set to '60'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 60) { + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: 60" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-003" + Task = "Ensure 'MinimumPasswordLength' is set to '14'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 14) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-004" + Task = "Ensure 'PasswordComplexity' is set to '1'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-005" + Task = "Ensure 'PasswordHistorySize' is set to '24'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-006" + Task = "Ensure 'LockoutBadCount' is set to '10'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 10) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: 10" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-007" + Task = "Ensure 'ResetLockoutCount' is set to '15'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 15) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-008" + Task = "Ensure 'LockoutDuration' is set to '15'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 15) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-009" + Task = "Ensure 'ClearTextPassword' is set to '0'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#AuditPolicies.ps1 new file mode 100644 index 0000000..6ef132e --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#AuditPolicies.ps1 @@ -0,0 +1,1274 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "AuditPolicy-001" + Task = "Ensure 'Credential Validation' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-002" + Task = "Ensure 'Other Account Management Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-003" + Task = "Ensure 'Security Group Management' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-004" + Task = "Ensure 'User Account Management' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-005" + Task = "Ensure 'PNP Activity' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-006" + Task = "Ensure 'Process Creation' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-007" + Task = "Ensure 'Account Lockout' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-008" + Task = "Ensure 'Group Membership' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-009" + Task = "Ensure 'Logoff' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-010" + Task = "Ensure 'Logon' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-011" + Task = "Ensure 'Special Logon' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-012" + Task = "Ensure 'Removable Storage' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-013" + Task = "Ensure 'Audit Policy Change' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-014" + Task = "Ensure 'Authentication Policy Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-015" + Task = "Ensure 'Authorization Policy Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-016" + Task = "Ensure 'Sensitive Privilege Use' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-017" + Task = "Ensure 'IPsec Driver' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory IPsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "IPsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'IPsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-018" + Task = "Ensure 'Other System Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-019" + Task = "Ensure 'Security State Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-020" + Task = "Ensure 'Security System Extension' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-021" + Task = "Ensure 'System Integrity' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#RegistrySettings.ps1 new file mode 100644 index 0000000..b3ef92d --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#RegistrySettings.ps1 @@ -0,0 +1,3658 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "Registry-001" + Task = "Ensure 'Turn off Autoplay' is set to 'All drives'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-002" + Task = "Ensure 'Set the default behavior for AutoRun' is set to 'Do not execute any autorun commands'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-003" + Task = "Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-004" + Task = "Set registry value 'LocalAccountTokenFilterPolicy' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-005" + Task = "Set registry value 'EnhancedAntiSpoofing' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-006" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '32768'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-007" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '196608'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-008" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '32768'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-009" + Task = "Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-010" + Task = "Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-011" + Task = "Ensure 'Turn off heap termination on corruption' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-012" + Task = "Ensure 'Configure registry policy processing' is set to '0'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-013" + Task = "Ensure 'Configure registry policy processing' is set to '0'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-014" + Task = "Set registry value 'AlwaysInstallElevated' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-015" + Task = "Ensure 'Allow user control over installs' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-016" + Task = "Ensure 'Enable insecure guest logons' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-017" + Task = "Set registry value '\\*\SYSVOL' to RequireMutualAuthentication=1, RequireIntegrity=1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if ($regValue -notmatch "^(?:RequireMutualAuthentication=1,\s*RequireIntegrity=1|RequireIntegrity=1,\s*RequireMutualAuthentication=1)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: RequireMutualAuthentication=1, RequireIntegrity=1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-018" + Task = "Set registry value '\\*\NETLOGON' to RequireMutualAuthentication=1, RequireIntegrity=1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if ($regValue -notmatch "^(?:RequireMutualAuthentication=1,\s*RequireIntegrity=1|RequireIntegrity=1,\s*RequireMutualAuthentication=1)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: RequireMutualAuthentication=1, RequireIntegrity=1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-019" + Task = "Set registry value 'NoLockScreenCamera' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-020" + Task = "Set registry value 'NoLockScreenSlideshow' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-021" + Task = "Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-022" + Task = "Ensure 'Turn on PowerShell Script Block Logging' is not set." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockInvocationLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockInvocationLogging" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-023" + Task = "Ensure 'Do not display network selection UI' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-024" + Task = "Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-025" + Task = "Ensure 'Configure Windows SmartScreen' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-026" + Task = "Set registry value 'AllowIndexingEncryptedStoresOrItems' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-027" + Task = "Ensure 'Allow Basic authentication' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-028" + Task = "Ensure 'Allow unencrypted traffic' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-029" + Task = "Ensure 'Disallow Digest authentication' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-030" + Task = "Ensure 'Allow Basic authentication' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-031" + Task = "Ensure 'Allow unencrypted traffic' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-032" + Task = "Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-033" + Task = "Set registry value 'MitigationOptions_FontBocking' to 1000000000000." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\MitigationOptions" ` + -Name "MitigationOptions_FontBocking" ` + | Select-Object -ExpandProperty "MitigationOptions_FontBocking" + + if ($regValue -ne "1000000000000") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1000000000000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-034" + Task = "Ensure 'Restrict Unauthenticated RPC clients' is set to 'Authenticated'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-035" + Task = "Set registry value 'DisablePasswordSaving' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-036" + Task = "Set registry value 'fDisableCdm' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-037" + Task = "Set registry value 'fPromptForPassword' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-038" + Task = "Set registry value 'fEncryptRPCTraffic' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-039" + Task = "Set registry value 'MinEncryptionLevel' to 3." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-041" + Task = "Domain: Set registry value 'DefaultOutboundAction' to 0." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-042" + Task = "Domain: Set registry value 'DefaultInboundAction' to 1." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-043" + Task = "Domain: Set registry value 'EnableFirewall' to 1." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-044" + Task = "Private: Set registry value 'EnableFirewall' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-045" + Task = "Private: Set registry value 'DefaultInboundAction' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-046" + Task = "Private: Set registry value 'DefaultOutboundAction' to 0." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-047" + Task = "Public: Set registry value 'EnableFirewall' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-048" + Task = "Public: Set registry value 'DefaultOutboundAction' to 0." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-049" + Task = "Public: Set registry value 'DefaultInboundAction' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-050" + Task = "Set registry value 'AdmPwdEnabled' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft Services\AdmPwd" ` + -Name "AdmPwdEnabled" ` + | Select-Object -ExpandProperty "AdmPwdEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-051" + Task = "Ensure 'WDigest Authentication (disabling may require KB2871997)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-052" + Task = "Set registry value 'DriverLoadPolicy' to 3." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-053" + Task = "Set registry value 'NoNameReleaseOnDemand' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NoNameReleaseOnDemand" ` + | Select-Object -ExpandProperty "NoNameReleaseOnDemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-054" + Task = "Set registry value 'EnableICMPRedirect' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-055" + Task = "Set registry value 'DisableIPSourceRouting' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-056" + Task = "Set registry value 'DisableIPSourceRouting' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-057" + Task = "Set registry value 'allownullsessionfallback' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "allownullsessionfallback" ` + | Select-Object -ExpandProperty "allownullsessionfallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-058" + Task = "Set registry value 'UseMachineId' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-059" + Task = "Set registry value 'InactivityTimeoutSecs' to 900." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if ($regValue -ne 900) { + return @{ + Message = "Registry value is '$regValue'. Expected: 900" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-060" + Task = "Set registry value 'ScRemoveOption' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-061" + Task = "Set registry value 'autodisconnect' to 15." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "autodisconnect" ` + | Select-Object -ExpandProperty "autodisconnect" + + if ($regValue -ne 15) { + return @{ + Message = "Registry value is '$regValue'. Expected: 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-062" + Task = "Set registry value 'SCENoApplyLegacyAuditPolicy' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-063" + Task = "Set registry value 'EnableVirtualization' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-064" + Task = "Set registry value 'FilterAdministratorToken' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-065" + Task = "Set registry value 'EnableLUA' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-066" + Task = "Set registry value 'EnableInstallerDetection' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-067" + Task = "Set registry value 'EnableUIADesktopToggle' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableUIADesktopToggle" ` + | Select-Object -ExpandProperty "EnableUIADesktopToggle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-068" + Task = "Set registry value 'ConsentPromptBehaviorAdmin' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-069" + Task = "Set registry value 'ConsentPromptBehaviorUser' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-070" + Task = "Set registry value 'EnableSecureUIAPaths' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-071" + Task = "Set registry value 'LDAPClientIntegrity' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-072" + Task = "Set registry value 'LmCompatibilityLevel' to 5." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-073" + Task = "Set registry value 'EveryoneIncludesAnonymous' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-074" + Task = "Set registry value 'enablesecuritysignature' to 1." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Registry-075" + Task = "Set registry value 'NTLMMinClientSec' to 537395200." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-076" + Task = "Set registry value 'sealsecurechannel' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "sealsecurechannel" ` + | Select-Object -ExpandProperty "sealsecurechannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-077" + Task = "Set registry value 'EnableSecuritySignature' to 1." + Test = { + try { + if((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Registry-078" + Task = "Set registry value 'NTLMMinServerSec' to 537395200." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-079" + Task = "Set registry value 'requiresignorseal' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "requiresignorseal" ` + | Select-Object -ExpandProperty "requiresignorseal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-080" + Task = "Set registry value 'signsecurechannel' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "signsecurechannel" ` + | Select-Object -ExpandProperty "signsecurechannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-081" + Task = "Set registry value 'RequireSecuritySignature' to 1." + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Registry-082" + Task = "Set registry value 'requiresecuritysignature' to 1." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Registry-083" + Task = "Set registry value 'requirestrongkey' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "requirestrongkey" ` + | Select-Object -ExpandProperty "requirestrongkey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-084" + Task = "Set registry value 'RestrictAnonymousSAM' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-085" + Task = "Set registry value 'RestrictNullSessAccess' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-086" + Task = "Set registry value 'ObCaseInsensitive' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-087" + Task = "Set registry value 'RestrictAnonymous' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-088" + Task = "Set registry value 'ProtectionMode' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-089" + Task = "Set registry value 'LimitBlankPasswordUse' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-090" + Task = "Set registry value 'maximumpasswordage' to 30." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "maximumpasswordage" ` + | Select-Object -ExpandProperty "maximumpasswordage" + + if ($regValue -ne 30) { + return @{ + Message = "Registry value is '$regValue'. Expected: 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-091" + Task = "Set registry value 'disablepasswordchange' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "disablepasswordchange" ` + | Select-Object -ExpandProperty "disablepasswordchange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-092" + Task = "Set registry value 'NoLMHash' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-093" + Task = "Set registry value 'EnablePlainTextPassword' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-094" + Task = "Set registry value 'RestrictRemoteSAM' to O:BAG:BAD:(A;;RC;;;BA)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictRemoteSAM" ` + | Select-Object -ExpandProperty "RestrictRemoteSAM" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-095" + Task = "Ensure 'Turn off Windows Defender' is set to 'Disabled'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender" ` + -Name "DisableAntiSpyware" ` + | Select-Object -ExpandProperty "DisableAntiSpyware" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-096" + Task = "Ensure 'Turn on behavior monitoring' is set to 'Enabled'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-097" + Task = "Ensure 'Scan removable drives' is set to 'Enabled'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-098" + Task = "Ensure 'Turn on e-mail scanning' is set to 'Enabled'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-099" + Task = "Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-100" + Task = "Ensure 'Send file samples when further analysis is required' is set to 'Send safe samples'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SubmitSamplesConsent" ` + | Select-Object -ExpandProperty "SubmitSamplesConsent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-101" + Task = "Ensure 'Join Microsoft MAPS' is set to 'Advanced MAPS'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-102" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-103" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Secure Boot and DMA Protection'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-104" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled with UEFI lock'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-105" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled with UEFI lock'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#UserRights.ps1 new file mode 100644 index 0000000..21afa41 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2016-Microsoft-FINAL#UserRights.ps1 @@ -0,0 +1,1031 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + if ($sidAccount.Translate([System.Security.Principal.NTAccount]) -eq "NULL SID") { + return @{ + Account = $null + Sid = $sidAccount.Value + } + } else { + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "UserRight-001" + Task = "Ensure 'SeSecurityPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-002" + Task = "Ensure 'SeCreateTokenPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-003" + Task = "Ensure 'SeTrustedCredManAccessPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-004" + Task = "Ensure 'SeCreatePagefilePrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-005" + Task = "Ensure 'SeRemoteShutdownPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-006" + Task = "Ensure 'SeDenyInteractiveLogonRight' is set to 'S-1-5-32-546'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-007" + Task = "Ensure 'SeIncreaseBasePriorityPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseBasePriorityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseBasePriorityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseBasePriorityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-008" + Task = "Ensure 'SeLoadDriverPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-009" + Task = "Ensure 'SeRestorePrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-010" + Task = "Ensure 'SeCreateGlobalPrivilege' is set to 'S-1-5-20, S-1-5-19, S-1-5-6, S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-20" + "S-1-5-19" + "S-1-5-6" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-011" + Task = "Ensure 'SeManageVolumePrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-012" + Task = "Ensure 'SeInteractiveLogonRight' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-013" + Task = "Ensure 'SeEnableDelegationPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-014" + Task = "Ensure 'SeCreatePermanentPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-015" + Task = "Ensure 'SeDebugPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-016" + Task = "Ensure 'SeProfileSingleProcessPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-017" + Task = "Ensure 'SeBackupPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-018" + Task = "Ensure 'SeNetworkLogonRight' is set to 'S-1-5-11, S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-11" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-019" + Task = "Ensure 'SeCreateSymbolicLinkPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-020" + Task = "Ensure 'SeDenyNetworkLogonRight' is set to 'S-1-5-114, S-1-5-32-546'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-114" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-021" + Task = "Ensure 'SeImpersonatePrivilege' is set to 'S-1-5-20, S-1-5-19, S-1-5-6, S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-20" + "S-1-5-19" + "S-1-5-6" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-022" + Task = "Ensure 'SeSystemEnvironmentPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-023" + Task = "Ensure 'SeLockMemoryPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-024" + Task = "Ensure 'SeTcbPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-025" + Task = "Ensure 'SeAuditPrivilege' is set to 'S-1-5-20, S-1-5-19'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-20" + "S-1-5-19" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-026" + Task = "Ensure 'SeTakeOwnershipPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-027" + Task = "Ensure 'SeDenyRemoteInteractiveLogonRight' is set to 'S-1-5-32-546, S-1-5-113'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#AccountPolicies.ps1 new file mode 100644 index 0000000..d00b68c --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#AccountPolicies.ps1 @@ -0,0 +1,283 @@ +[AuditTest] @{ + Id = "1.1.1" + Task = "(L1) Ensure 'Enforce password history' is set to '24 or more password(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "(L1) Ensure 'Maximum password age' is set to '365 or fewer days, but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 365 -or $setPolicy -le 0)) { + if($setPolicy -eq -1){ #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 365 days and x > 0 days" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "(L1) Ensure 'Minimum password age' is set to '1 or more day(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -lt 1) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1 days" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "(L1) Ensure 'Minimum password length' is set to '14 or more character(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -lt 14) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.5" + Task = "(L1) Ensure 'Password must meet complexity requirements' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.6" + Task = "(L1) Ensure 'Store passwords using reversible encryption' is set to 'Disabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "(L1) Ensure 'Account lockout duration' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -lt 15 -or $setPolicy -gt 99999) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15 minutes and x <= 99999 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "(L1) Ensure 'Account lockout threshold' is set to '5 or fewer invalid logon attempt(s), but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -gt 5 -or $setPolicy -le 0) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 5 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.3" + Task = "(L1) Ensure 'Allow Administrator account lockout' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["AllowAdministratorLockout"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'AllowAdministratorLockout' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.4" + Task = "(L1) Ensure 'Reset account lockout counter after' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -gt 99999 -or $setPolicy -lt 15) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x <= 99999 minutes and x >= 15 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#AuditPolicies.ps1 new file mode 100644 index 0000000..da2f9f0 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#AuditPolicies.ps1 @@ -0,0 +1,2036 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "17.1.1" + Task = "(L1) Ensure 'Audit Credential Validation' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.1.2" + Task = "(L1) Ensure 'Audit Kerberos Authentication Service' is set to 'Success and Failure' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Kerberos Authentication Service + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kerberos Authentication Service" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kerberos Authentication Service'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.1.3" + Task = "(L1) Ensure 'Audit Kerberos Service Ticket Operations' is set to 'Success and Failure' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Kerberos Service Ticket Operations + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kerberos Service Ticket Operations" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kerberos Service Ticket Operations'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.1" + Task = "(L1) Ensure 'Audit Application Group Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Application Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Application Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Application Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.2" + Task = "(L1) Ensure 'Audit Computer Account Management' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Computer Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Computer Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Computer Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.3" + Task = "(L1) Ensure 'Audit Distribution Group Management' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Distribution Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Distribution Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Distribution Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.4" + Task = "(L1) Ensure 'Audit Other Account Management Events' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.5" + Task = "(L1) Ensure 'Audit Security Group Management' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.6" + Task = "(L1) Ensure 'Audit User Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.1" + Task = "(L1) Ensure 'Audit PNP Activity' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.2" + Task = "(L1) Ensure 'Audit Process Creation' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.4.1" + Task = "(L1) Ensure 'Audit Directory Service Access' is set to include 'Failure' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Directory Service Access + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Access" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Access'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.4.2" + Task = "(L1) Ensure 'Audit Directory Service Changes' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Directory Service Changes + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Changes" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Changes'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.1" + Task = "(L1) Ensure 'Audit Account Lockout' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.2" + Task = "(L1) Ensure 'Audit Group Membership' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.3" + Task = "(L1) Ensure 'Audit Logoff' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.4" + Task = "(L1) Ensure 'Audit Logon' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.5" + Task = "(L1) Ensure 'Audit Other Logon/Logoff Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.6" + Task = "(L1) Ensure 'Audit Special Logon' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.1" + Task = "(L1) Ensure 'Audit Detailed File Share' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.2" + Task = "(L1) Ensure 'Audit File Share' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.3" + Task = "(L1) Ensure 'Audit Other Object Access Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.4" + Task = "(L1) Ensure 'Audit Removable Storage' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.1" + Task = "(L1) Ensure 'Audit Audit Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.2" + Task = "(L1) Ensure 'Audit Authentication Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.3" + Task = "(L1) Ensure 'Audit Authorization Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.4" + Task = "(L1) Ensure 'Audit MPSSVC Rule-Level Policy Change' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Mpssvc Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Mpssvc Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Mpssvc Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.5" + Task = "(L1) Ensure 'Audit Other Policy Change Events' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.8.1" + Task = "(L1) Ensure 'Audit Sensitive Privilege Use' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.1" + Task = "(L1) Ensure 'Audit IPsec Driver' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Ipsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Ipsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Ipsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.2" + Task = "(L1) Ensure 'Audit Other System Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.3" + Task = "(L1) Ensure 'Audit Security State Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.4" + Task = "(L1) Ensure 'Audit Security System Extension' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.5" + Task = "(L1) Ensure 'Audit System Integrity' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#RegistrySettings.ps1 new file mode 100644 index 0000000..eb0281c --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#RegistrySettings.ps1 @@ -0,0 +1,12919 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "2.3.1.1" + Task = "(L1) Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "NoConnectedUser" ` + | Select-Object -ExpandProperty "NoConnectedUser" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.3" + Task = "(L1) Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.1" + Task = "(L1) Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.2" + Task = "(L1) Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "CrashOnAuditFail" ` + | Select-Object -ExpandProperty "CrashOnAuditFail" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4.1" + Task = "(L1) Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.1" + Task = "(L1) Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SubmitControl" ` + | Select-Object -ExpandProperty "SubmitControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.2" + Task = "(L1) Ensure 'Domain controller: Allow vulnerable Netlogon secure channel connections' is set to 'Not Configured' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "vulnerablechannelallowlist" ` + | Select-Object -ExpandProperty "vulnerablechannelallowlist" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.3" + Task = "(L1) Ensure 'Domain controller: LDAP server channel binding token requirements' is set to 'Always' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LdapEnforceChannelBinding" ` + | Select-Object -ExpandProperty "LdapEnforceChannelBinding" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.4" + Task = "(L1) Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LDAPServerIntegrity" ` + | Select-Object -ExpandProperty "LDAPServerIntegrity" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.5" + Task = "(L1) Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RefusePasswordChange" ` + | Select-Object -ExpandProperty "RefusePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.1" + Task = "(L1) Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.2" + Task = "(L1) Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.3" + Task = "(L1) Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.4" + Task = "(L1) Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.5" + Task = "(L1) Ensure 'Domain member: Maximum machine account password age' is set to '30 or fewer days, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if ($regValue -le 0 -or $regValue -gt 30) { + return @{ + Message = "Registry value is '$regValue'. Expected: x > 0 and x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.6" + Task = "(L1) Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.1" + Task = "(L1) Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.2" + Task = "(L1) Ensure 'Interactive logon: Don't display last signed-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.3" + Task = "(L1) Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if ($regValue -gt 900 -or $regValue -eq 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.4" + Task = "(L1) Configure 'Interactive logon: Message text for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.5" + Task = "(L1) Configure 'Interactive logon: Message title for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.6" + Task = "(L2) Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "CachedLogonsCount" ` + | Select-Object -ExpandProperty "CachedLogonsCount" + + if ($regValue -notmatch "^[43210]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[43210]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.7" + Task = "(L1) Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if ($regValue -gt 14 -or $regValue -lt 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 14 and x >= 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.8" + Task = "(L1) Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ForceUnlockLogon" ` + | Select-Object -ExpandProperty "ForceUnlockLogon" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.9" + Task = "(L1) Ensure 'Interactive logon: Smart card removal behavior' is set to 1 - 'Lock Workstation' or 2 / 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -notmatch "^(1|2|3)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(1|2|3)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.8.1" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.2" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.3" + Task = "(L1) Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.1" + Task = "(L1) Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if ($regValue -gt 15) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.2" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.3" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.4" + Task = "(L1) Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "enableforcedlogoff" ` + | Select-Object -ExpandProperty "enableforcedlogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.5" + Task = "(L1) Ensure 'Microsoft network server: Server SPN target name validation level' is set to 1 - 'Accept if provided by client' or 2 - higher (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "SMBServerNameHardeningLevel" ` + | Select-Object -ExpandProperty "SMBServerNameHardeningLevel" + + if ($regValue -ne 1 -and $regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.2" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.3" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.4" + Task = "(L2) Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.5" + Task = "(L1) Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.6" + Task = "(L1) Configure 'Network access: Named Pipes that can be accessed anonymously' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + $reference = @( + "LSARPC" + "NETLOGON" + "SAMR" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: LSARPC NETLOGON SAMR" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.7" + Task = "(L1) Configure 'Network access: Named Pipes that can be accessed anonymously' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.8" + Task = "(L1) Configure 'Network access: Remotely accessible registry paths'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\ProductOptions" + "System\CurrentControlSet\Control\Server Applications" + "Software\Microsoft\Windows NT\CurrentVersion" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\ProductOptions System\CurrentControlSet\Control\Server Applications Software\Microsoft\Windows NT\CurrentVersion" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +$CARoleStatus = (Get-WindowsFeature -Name ADCS-Cert-Authority).Installed +$WINSStatus = (Get-WindowsFeature -Name WINS).Installed +[AuditTest] @{ + Id = "2.3.10.9 A" + Task = "(L1) Configure 'Network access: Remotely accessible registry paths and sub-paths' [WINS Role Feature and CA Role Service NOT installed]" + Test = { + try { + if (($CARoleStatus -or $WINSStatus) -eq $true){ + return @{ + Message = "WINS Role Feature or CA Role Service are installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9 B" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured [CA Role Service installed]" + Test = { + try { + if ($CARoleStatus -eq $false){ + return @{ + Message = "CA Role Service NOT installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + "System\CurrentControlSet\Services\CertSvc" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog System\CurrentControlSet\Services\CertSvc" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9 C" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured [WINS Role Feature installed]" + Test = { + try { + if ($WINSStatus -eq $false){ + return @{ + Message = "WINS Role Feature NOT installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + "System\CurrentControlSet\Services\WINS" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog System\CurrentControlSet\Services\WINS" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.10" + Task = "(L1) Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.11" + Task = "(L1) Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "restrictremotesam" ` + | Select-Object -ExpandProperty "restrictremotesam" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.12" + Task = "(L1) Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionShares" ` + | Select-Object -ExpandProperty "NullSessionShares" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.13" + Task = "(L1) Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.1" + Task = "(L1) Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.2" + Task = "(L1) Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.3" + Task = "(L1) Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.4" + Task = "(L1) Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.5" + Task = "(L1) Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.7" + Task = "(L1) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.8" + Task = "(L1) Ensure 'Network security: LDAP client signing requirements' is set to 1 - 'Negotiate signing' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1 -and $regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.9" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.10" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.11" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Audit Incoming NTLM Traffic' is set to 'Enable auditing for all accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AuditReceivingNTLMTraffic" ` + | Select-Object -ExpandProperty "AuditReceivingNTLMTraffic" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.12" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Audit NTLM authentication in this domain' is set to 'Enable all' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "AuditNTLMInDomain" ` + | Select-Object -ExpandProperty "AuditNTLMInDomain" + + if ($regValue -ne 7) { + return @{ + Message = "Registry value is '$regValue'. Expected: 7" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.13" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers' is set to 1 - 'Audit all' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "RestrictSendingNTLMTraffic" ` + | Select-Object -ExpandProperty "RestrictSendingNTLMTraffic" + + if ($regValue -ne 1 -and $regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.13.1" + Task = "(L1) Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ShutdownWithoutLogon" ` + | Select-Object -ExpandProperty "ShutdownWithoutLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.1" + Task = "(L1) Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.2" + Task = "(L1) Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.1" + Task = "(L1) Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.2" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 2 - 'Prompt for consent on the secure desktop' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if ($regValue -ne 1 -and $regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.3" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.4" + Task = "(L1) Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.5" + Task = "(L1) Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.6" + Task = "(L1) Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.7" + Task = "(L1) Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.8" + Task = "(L1) Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1" + Task = "(L1) Ensure 'Print Spooler (Spooler)' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2" + Task = "(L2) Ensure 'Print Spooler (Spooler)' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.1.1" + Task = "(L1) Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.2" + Task = "(L1) Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.3" + Task = "(L1) Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.4" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\domainfw.log'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\domainfw.log"; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.5" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.6" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.7" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.1" + Task = "(L1) Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.2" + Task = "(L1) Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.3" + Task = "(L1) Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.4" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\privatefw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\privatefw.log"; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.5" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.6" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.7" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.1" + Task = "(L1) Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.2" + Task = "(L1) Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.3" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.4" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.5" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.6" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\publicfw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\publicfw.log"; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.7" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.8" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.9" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "18.1.1.1" + Task = "(L1) Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.1.2" + Task = "(L1) Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.2.2" + Task = "(L1) Ensure 'Allow users to enable online speech recognition services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "AllowInputPersonalization" ` + | Select-Object -ExpandProperty "AllowInputPersonalization" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.3" + Task = "(L2) Ensure 'Allow Online Tips' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "AllowOnlineTips" ` + | Select-Object -ExpandProperty "AllowOnlineTips" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.1" + Task = "(L1) Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.2" + Task = "(L1) Ensure 'Configure RPC packet level privacy setting for incoming connections' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print" ` + -Name "RpcAuthnLevelPrivacyEnabled" ` + | Select-Object -ExpandProperty "RpcAuthnLevelPrivacyEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.3" + Task = "(L1) Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.4" + Task = "(L1) Ensure 'Configure SMB v1 server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.5" + Task = "(L1) Ensure 'Enable Certificate Padding' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Wintrust\Config" ` + -Name "EnableCertPaddingCheck" ` + | Select-Object -ExpandProperty "EnableCertPaddingCheck" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.6" + Task = "(L1) Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.7" + Task = "(L1) Ensure 'LSA Protection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RunAsPPL" ` + | Select-Object -ExpandProperty "RunAsPPL" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.8" + Task = "(L1) Ensure 'NetBT NodeType configuration' is set to 'Enabled: P-node (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.9" + Task = "(L1) Ensure 'WDigest Authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.1" + Task = "(L1) Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.2" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.3" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.4" + Task = "(L1) Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.5" + Task = "(L2) Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "KeepAliveTime" ` + | Select-Object -ExpandProperty "KeepAliveTime" + + if ($regValue -ne 300000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 300000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.6" + Task = "(L1) Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.7" + Task = "(L2) Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "PerformRouterDiscovery" ` + | Select-Object -ExpandProperty "PerformRouterDiscovery" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.8" + Task = "(L1) Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.9" + Task = "(L1) Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScreenSaverGracePeriod" ` + | Select-Object -ExpandProperty "ScreenSaverGracePeriod" + + if ($regValue -notmatch "^[0-5]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[0-5]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.10" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.11" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.12" + Task = "(L1) Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security" ` + -Name "WarningLevel" ` + | Select-Object -ExpandProperty "WarningLevel" + + if ($regValue -gt 90) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 90" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.1" + Task = "(L1) Ensure 'Configure NetBIOS settings' is set to 2 - 'Enabled: Disable NetBIOS name resolution on public networks' or 0 - 'Enabled: Disable NetBIOS name resolution'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableNetBIOS" ` + | Select-Object -ExpandProperty "EnableNetBIOS" + + if ($regValue -ne 2 -and $regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2 or 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.2" + Task = "(L1) Ensure 'Turn off multicast name resolution' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.5.1" + Task = "(L2) Ensure 'Enable Font Providers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableFontProviders" ` + | Select-Object -ExpandProperty "EnableFontProviders" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.1" + Task = "(L1) Ensure 'Enable insecure guest logons' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 A" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnDomain" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 B" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnPublicNet" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 C" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (EnableLLTDIO)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableLLTDIO" ` + | Select-Object -ExpandProperty "EnableLLTDIO" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 D" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitLLTDIOOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitLLTDIOOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 A" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnDomain" ` + | Select-Object -ExpandProperty "AllowRspndrOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 B" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnPublicNet" ` + | Select-Object -ExpandProperty "AllowRspndrOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 C" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (EnableRspndr)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableRspndr" ` + | Select-Object -ExpandProperty "EnableRspndr" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 D" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitRspndrOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitRspndrOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.10.2" + Task = "(L2) Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Peernet" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.2" + Task = "(L1) Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.3" + Task = "(L1) Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.4" + Task = "(L1) Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_StdDomainUserSetLocation" ` + | Select-Object -ExpandProperty "NC_StdDomainUserSetLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 A" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares' (\\*\NETLOGON)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "Require Privacy") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 B" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares' (\\*\SYSVOL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "Require Privacy") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.19.2.1" + Task = "(L2) Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "DisabledComponents" ` + | Select-Object -ExpandProperty "DisabledComponents" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 A" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (EnableRegistrars)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "EnableRegistrars" ` + | Select-Object -ExpandProperty "EnableRegistrars" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 B" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableUPnPRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableUPnPRegistrar" ` + | Select-Object -ExpandProperty "DisableUPnPRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 C" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableInBand802DOT11Registrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableInBand802DOT11Registrar" ` + | Select-Object -ExpandProperty "DisableInBand802DOT11Registrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 D" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableFlashConfigRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableFlashConfigRegistrar" ` + | Select-Object -ExpandProperty "DisableFlashConfigRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 E" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableWPDRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableWPDRegistrar" ` + | Select-Object -ExpandProperty "DisableWPDRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.2" + Task = "(L2) Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\UI" ` + -Name "DisableWcnUi" ` + | Select-Object -ExpandProperty "DisableWcnUi" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.1" + Task = "(L1) Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled: 3 = Prevent Wi-Fi when on Ethernet'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fMinimizeConnections" ` + | Select-Object -ExpandProperty "fMinimizeConnections" + + if ($null -eq $regValue -or $regValue -gt 3 -or $regValue -lt 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1-3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.2" + Task = "(L2) Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.1" + Task = "(L1) Ensure 'Allow Print Spooler to accept client connections' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "RegisterSpoolerRemoteRpcEndPoint" ` + | Select-Object -ExpandProperty "RegisterSpoolerRemoteRpcEndPoint" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.2" + Task = "(L1) Ensure 'Configure Redirection Guard' is set to 'Enabled: Redirection Guard Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "RedirectionGuardPolicy" ` + | Select-Object -ExpandProperty "RedirectionGuardPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.3" + Task = "(L1) Ensure 'Configure RPC connection settings: Protocol to use for outgoing RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcUseNamedPipeProtocol" ` + | Select-Object -ExpandProperty "RpcUseNamedPipeProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.4" + Task = "(L1) Ensure 'Configure RPC connection settings: Use authentication for outgoing RPC connections' is set to 'Enabled: Default'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcAuthentication" ` + | Select-Object -ExpandProperty "RpcAuthentication" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.5" + Task = "(L1) Ensure 'Configure RPC listener settings: Protocols to allow for incoming RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcProtocols" ` + | Select-Object -ExpandProperty "RpcProtocols" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.6" + Task = "(L1) Ensure 'Configure RPC listener settings: Authentication protocol to use for incoming RPC connections:' is set to 'Enabled: 0 - Negotiate' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "ForceKerberosForRpc" ` + | Select-Object -ExpandProperty "ForceKerberosForRpc" + + if ($regValue -ne 0 -and $regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0 or 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.7" + Task = "(L1) Ensure 'Configure RPC over TCP port' is set to 'Enabled: 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcTcpPort" ` + | Select-Object -ExpandProperty "RpcTcpPort" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.8" + Task = "(L1) Ensure 'Limits print driver installation to Administrators' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "RestrictDriverInstallationToAdministrators" ` + | Select-Object -ExpandProperty "RestrictDriverInstallationToAdministrators" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.9" + Task = "(L1) Ensure 'Manage processing of Queue-specific files' is set to 'Enabled: Limit Queue-specific files to Color profiles'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "CopyFilesPolicy" ` + | Select-Object -ExpandProperty "CopyFilesPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.10" + Task = "(L1) Ensure 'Point and Print Restrictions: When installing drivers for a new connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "NoWarningNoElevationOnInstall" ` + | Select-Object -ExpandProperty "NoWarningNoElevationOnInstall" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.11" + Task = "(L1) Ensure 'Point and Print Restrictions: When updating drivers for an existing connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "UpdatePromptSettings" ` + | Select-Object -ExpandProperty "UpdatePromptSettings" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.1.1" + Task = "(L2) Ensure 'Turn off notifications network usage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.3.1" + Task = "(L1) Ensure 'Include command line in process creation events' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.1" + Task = "(L1) Ensure 'Encryption Oracle Remediation' is set to 'Enabled: Force Updated Clients'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.2" + Task = "(L1) Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.1" + Task = "(NG) Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.2" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Select Platform Security Level' is set to 1 - 'Secure Boot' or 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if ($regValue -ne 1 -and $regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.3" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Virtualization Based Protection of Code Integrity' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.4" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Require UEFI Memory Attributes Table' is set to 'True (checked)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HVCIMATRequired" ` + | Select-Object -ExpandProperty "HVCIMATRequired" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.5" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Enabled with UEFI lock' (MS Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.6" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Disabled' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.7" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Secure Launch Configuration' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureSystemGuardLaunch" ` + | Select-Object -ExpandProperty "ConfigureSystemGuardLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.2" + Task = "(L1) Ensure 'Prevent device metadata retrieval from the Internet' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" ` + -Name "PreventDeviceMetadataFromNetwork" ` + | Select-Object -ExpandProperty "PreventDeviceMetadataFromNetwork" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.13.1" + Task = "(L1) Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.2" + Task = "(L1) Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.3" + Task = "(L1) Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.4" + Task = "(L1) Ensure 'Configure security policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.5" + Task = "(L1) Ensure 'Configure security policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.6" + Task = "(L1) Ensure 'Continue experiences on this device' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableCdp" ` + | Select-Object -ExpandProperty "EnableCdp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.7" + Task = "(L1) Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableBkGndGroupPolicy" ` + | Select-Object -ExpandProperty "DisableBkGndGroupPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.1" + Task = "(L1) Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.2" + Task = "(L2) Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TabletPC" ` + -Name "PreventHandwritingDataSharing" ` + | Select-Object -ExpandProperty "PreventHandwritingDataSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.3" + Task = "(L2) Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HandwritingErrorReports" ` + -Name "PreventHandwritingErrorReports" ` + | Select-Object -ExpandProperty "PreventHandwritingErrorReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.4" + Task = "(L2) Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Internet Connection Wizard" ` + -Name "ExitOnMSICW" ` + | Select-Object -ExpandProperty "ExitOnMSICW" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.5" + Task = "(L1) Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.6" + Task = "(L2) Ensure 'Turn off printing over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.7" + Task = "(L2) Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Registration Wizard Control" ` + -Name "NoRegistration" ` + | Select-Object -ExpandProperty "NoRegistration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.8" + Task = "(L2) Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SearchCompanion" ` + -Name "DisableContentFileUpdates" ` + | Select-Object -ExpandProperty "DisableContentFileUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.9" + Task = "(L2) Ensure 'Turn off the `"Order Prints`" picture task' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoOnlinePrintsWizard" ` + | Select-Object -ExpandProperty "NoOnlinePrintsWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.10" + Task = "(L2) Ensure 'Turn off the `"Publish to Web`" task for files and folders' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoPublishingWizard" ` + | Select-Object -ExpandProperty "NoPublishingWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.11" + Task = "(L2) Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Messenger\Client" ` + -Name "CEIP" ` + | Select-Object -ExpandProperty "CEIP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.12" + Task = "(L2) Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SQMClient\Windows" ` + -Name "CEIPEnable" ` + | Select-Object -ExpandProperty "CEIPEnable" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13 A" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (Disabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13 B" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (DoReport)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\PCHealth\ErrorReporting" ` + -Name "DoReport" ` + | Select-Object -ExpandProperty "DoReport" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 A" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitBehavior)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitBehavior" ` + | Select-Object -ExpandProperty "DevicePKInitBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 B" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitEnabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitEnabled" ` + | Select-Object -ExpandProperty "DevicePKInitEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.1" + Task = "(L1) Ensure 'Enumeration policy for external devices incompatible with Kernel DMA Protection' is set to 'Enabled: Block All'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.1" + Task = "(L1) Ensure 'Configure password backup directory' is set to 2 - 'Enabled: Active Directory' or 1 - 'Enabled: Azure Active Directory'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "BackupDirectory" ` + | Select-Object -ExpandProperty "BackupDirectory" + + if ($regValue -ne 1 -and $regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.2" + Task = "(L1) Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PwdExpirationProtectionEnabled" ` + | Select-Object -ExpandProperty "PwdExpirationProtectionEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.3" + Task = "(L1) Ensure 'Enable password encryption' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "ADPasswordEncryptionEnabled" ` + | Select-Object -ExpandProperty "ADPasswordEncryptionEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.4" + Task = "(L1) Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordComplexity" ` + | Select-Object -ExpandProperty "PasswordComplexity" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.5" + Task = "(L1) Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordLength" ` + | Select-Object -ExpandProperty "PasswordLength" + + if ($regValue -lt 15) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.6" + Task = "(L1) Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordAgeDays" ` + | Select-Object -ExpandProperty "PasswordAgeDays" + + if ($regValue -gt 30 -or $regValue -lt 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30 and x >= 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.7" + Task = "(L1) Ensure 'Post-authentication actions: Grace period (hours)' is set to 'Enabled: 8 or fewer hours, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PostAuthenticationResetDelay" ` + | Select-Object -ExpandProperty "PostAuthenticationResetDelay" + + if ($regValue -gt 8 -or $regValue -le 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 8 and x > 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.8" + Task = "(L1) Ensure 'Post-authentication actions: Actions' is set to 3 - 'Enabled: Reset the password and logoff the managed account' or 5 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PostAuthenticationActions" ` + | Select-Object -ExpandProperty "PostAuthenticationActions" + + if ($regValue -ne 3 -and $regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3 or 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.1" + Task = "(L2) Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Control Panel\International" ` + -Name "BlockUserInputMethodsForSignIn" ` + | Select-Object -ExpandProperty "BlockUserInputMethodsForSignIn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.1" + Task = "(L1) Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockUserFromShowingAccountDetailsOnSignin" ` + | Select-Object -ExpandProperty "BlockUserFromShowingAccountDetailsOnSignin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.2" + Task = "(L1) Ensure 'Do not display network selection UI' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.3" + Task = "(L1) Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontEnumerateConnectedUsers" ` + | Select-Object -ExpandProperty "DontEnumerateConnectedUsers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.4" + Task = "(L1) Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.5" + Task = "(L1) Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.6" + Task = "(L1) Ensure 'Turn off picture password sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "BlockDomainPicturePassword" ` + | Select-Object -ExpandProperty "BlockDomainPicturePassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.7" + Task = "(L1) Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.31.1" + Task = "(L2) Ensure 'Allow Clipboard synchronization across devices' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowCrossDeviceClipboard" ` + | Select-Object -ExpandProperty "AllowCrossDeviceClipboard" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.31.2" + Task = "(L2) Ensure 'Allow upload of User Activities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "UploadUserActivities" ` + | Select-Object -ExpandProperty "UploadUserActivities" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.1" + Task = "(L2) Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.2" + Task = "(L2) Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.3" + Task = "(L1) Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.4" + Task = "(L1) Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.1" + Task = "(L1) Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.2" + Task = "(L1) Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.36.1" + Task = "(L1) Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "EnableAuthEpResolution" ` + | Select-Object -ExpandProperty "EnableAuthEpResolution" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.36.2" + Task = "(L2) Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1" + Task = "(L2) Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.11.1" + Task = "(L2) Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d}" ` + -Name "ScenarioExecutionEnabled" ` + | Select-Object -ExpandProperty "ScenarioExecutionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.49.1" + Task = "(L2) Ensure 'Turn off the advertising ID' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" ` + -Name "DisabledByGroupPolicy" ` + | Select-Object -ExpandProperty "DisabledByGroupPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.51.1.1" + Task = "(L1) Ensure 'Enable Windows NTP Client' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.51.1.2" + Task = "(L1) Ensure 'Enable Windows NTP Server' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.3.1" + Task = "(L2) Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager" ` + -Name "AllowSharedLocalAppData" ` + | Select-Object -ExpandProperty "AllowSharedLocalAppData" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.5.1" + Task = "(L1) Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.1" + Task = "(L1) Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.2" + Task = "(L1) Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.3" + Task = "(L1) Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.8.1.1" + Task = "(L1) Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1" + Task = "(L2) Ensure 'Allow Use of Camera' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera" ` + -Name "AllowCamera" ` + | Select-Object -ExpandProperty "AllowCamera" + + if ($regValue -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam" ` + -Name "Value" ` + | Select-Object -ExpandProperty "Value" + + if ($regValue -match "Deny") { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Camera is not deactivated." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "18.10.12.1" + Task = "(L1) Ensure 'Turn off cloud consumer account state content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableConsumerAccountStateContent" ` + | Select-Object -ExpandProperty "DisableConsumerAccountStateContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.12.2" + Task = "(L1) Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.13.1" + Task = "(L1) Ensure 'Require pin for pairing' is set to 'Enabled: First Time' OR 'Enabled: Always'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect" ` + -Name "RequirePinForPairing" ` + | Select-Object -ExpandProperty "RequirePinForPairing" + + if ($regValue -ne 1 -and $regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.1" + Task = "(L1) Ensure 'Do not display the password reveal button' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.2" + Task = "(L1) Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.1" + Task = "(L1) Ensure 'Allow Diagnostic Data' is set to '0 - Enabled: Diagnostic data off (not recommended)' or '1 - Enabled: Send required diagnostic data'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + if ($regValue -ne 0 -and $regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0 or 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.2" + Task = "(L2) Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableEnterpriseAuthProxy" ` + | Select-Object -ExpandProperty "DisableEnterpriseAuthProxy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.3" + Task = "(L1) Ensure 'Disable OneSettings Downloads' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableOneSettingsDownloads" ` + | Select-Object -ExpandProperty "DisableOneSettingsDownloads" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.4" + Task = "(L1) Ensure 'Do not show feedback notifications' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DoNotShowFeedbackNotifications" ` + | Select-Object -ExpandProperty "DoNotShowFeedbackNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.5" + Task = "(L1) Ensure 'Enable OneSettings Auditing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "EnableOneSettingsAuditing" ` + | Select-Object -ExpandProperty "EnableOneSettingsAuditing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.6" + Task = "(L1) Ensure 'Limit Diagnostic Log Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDiagnosticLogCollection" ` + | Select-Object -ExpandProperty "LimitDiagnosticLogCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.7" + Task = "(L1) Ensure 'Limit Dump Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDumpCollection" ` + | Select-Object -ExpandProperty "LimitDumpCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.8" + Task = "(L1) Ensure 'Toggle user control over Insider builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" ` + -Name "AllowBuildPreview" ` + | Select-Object -ExpandProperty "AllowBuildPreview" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.1" + Task = "(L1) Ensure 'Enable App Installer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableAppInstaller" ` + | Select-Object -ExpandProperty "EnableAppInstaller" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.2" + Task = "(L1) Ensure 'Enable App Installer Experimental Features' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableExperimentalFeatures" ` + | Select-Object -ExpandProperty "EnableExperimentalFeatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.3" + Task = "(L1) Ensure 'Enable App Installer Hash Override' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableHashOverride" ` + | Select-Object -ExpandProperty "EnableHashOverride" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.4" + Task = "(L1) Ensure 'Enable App Installer ms-appinstaller protocol' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableMSAppInstallerProtocol" ` + | Select-Object -ExpandProperty "EnableMSAppInstallerProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.1.1" + Task = "(L1) Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.1.2" + Task = "(L1) Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.2.1" + Task = "(L1) Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.2.2" + Task = "(L1) Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.3.1" + Task = "(L1) Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.3.2" + Task = "(L1) Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.4.1" + Task = "(L1) Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.4.2" + Task = "(L1) Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -lt 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.28.2" + Task = "(L1) Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.28.3" + Task = "(L1) Ensure 'Turn off heap termination on corruption' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.28.4" + Task = "(L1) Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.36.1" + Task = "(L2) Ensure 'Turn off location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.40.1" + Task = "(L2) Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging" ` + -Name "AllowMessageSync" ` + | Select-Object -ExpandProperty "AllowMessageSync" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.41.1" + Task = "(L1) Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount" ` + -Name "DisableUserAuth" ` + | Select-Object -ExpandProperty "DisableUserAuth" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.5.1" + Task = "(L1) Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.5.2" + Task = "(L2) Ensure 'Join Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.1" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 A" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office communication application from creating child processes'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 B" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating executable content'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 C" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block abuse of exploited vulnerable signed drivers'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 D" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block execution of potentially obfuscated scripts'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 E" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from injecting code into other processes'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 F" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Adobe Reader from creating child processes'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 G" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Win32 API calls from Office macro'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 H" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block credential stealing from the Windows local security authority subsystem (lsass.exe)'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 I" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block untrusted and unsigned processes that run from USB'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 J" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block executable content from email client and webmail'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 K" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block JavaScript or VBScript from launching downloaded executable content'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 L" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating child processes'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 M" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block persistence through WMI event subscription'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } +} +} +[AuditTest] @{ + Id = "18.10.42.6.3.1" + Task = "(L1) Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.7.1" + Task = "(L1) Ensure 'Enable file hash computation feature' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\MpEngine" ` + -Name "EnableFileHashComputation" ` + | Select-Object -ExpandProperty "EnableFileHashComputation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.1" + Task = "(L1) Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.2" + Task = "(L1) Ensure 'Turn off real-time protection' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.3" + Task = "(L1) Ensure 'Turn on behavior monitoring' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.4" + Task = "(L1) Ensure 'Turn on script scanning' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableScriptScanning" ` + | Select-Object -ExpandProperty "DisableScriptScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.12.1" + Task = "(L2) Ensure 'Configure Watson events' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" ` + -Name "DisableGenericReports" ` + | Select-Object -ExpandProperty "DisableGenericReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.13.1" + Task = "(L1) Ensure 'Scan packed executables' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisablePackedExeScanning" ` + | Select-Object -ExpandProperty "DisablePackedExeScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.13.2" + Task = "(L1) Ensure 'Scan removable drives' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.13.3" + Task = "(L1) Ensure 'Turn on e-mail scanning' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.16" + Task = "(L1) Ensure 'Configure detection for potentially unwanted applications' is set to 'Enabled: Block'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.17" + Task = "(L1) Ensure 'Turn off Microsoft Defender AntiVirus' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "DisableAntiSpyware" ` + | Select-Object -ExpandProperty "DisableAntiSpyware" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.50.1" + Task = "(L1) Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.55.1" + Task = "(L2) Ensure 'Turn off Push To Install service' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall" ` + -Name "DisablePushToInstall" ` + | Select-Object -ExpandProperty "DisablePushToInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.2.2" + Task = "(L1) Ensure 'Do not allow passwords to be saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.2.1" + Task = "(L2) Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fSingleSessionPerUser" ` + | Select-Object -ExpandProperty "fSingleSessionPerUser" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.1" + Task = "(L2) Ensure 'Do not allow COM port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCcm" ` + | Select-Object -ExpandProperty "fDisableCcm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.2" + Task = "(L1) Ensure 'Do not allow drive redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.3" + Task = "(L2) Ensure 'Do not allow LPT port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLPT" ` + | Select-Object -ExpandProperty "fDisableLPT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.4" + Task = "(L2) Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisablePNPRedir" ` + | Select-Object -ExpandProperty "fDisablePNPRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.1" + Task = "(L1) Ensure 'Always prompt for password upon connection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.2" + Task = "(L1) Ensure 'Require secure RPC communication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.3" + Task = "(L1) Ensure 'Require use of specific security layer for remote (RDP) connections' is set to 'Enabled: SSL'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SecurityLayer" ` + | Select-Object -ExpandProperty "SecurityLayer" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.4" + Task = "(L1) Ensure 'Require user authentication for remote connections by using Network Level Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "UserAuthentication" ` + | Select-Object -ExpandProperty "UserAuthentication" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.5" + Task = "(L1) Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.10.1" + Task = "(L2) Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less, but not Never (0)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxIdleTime" ` + | Select-Object -ExpandProperty "MaxIdleTime" + + if ($regValue -gt 900000 -or $regValue -eq 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900000 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.10.2" + Task = "(L2) Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxDisconnectionTime" ` + | Select-Object -ExpandProperty "MaxDisconnectionTime" + + if ($regValue -ne 60000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 60000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.11.1" + Task = "(L1) Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.11.2" + Task = "(L1) Ensure 'Do not use temporary folders per session' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "PerSessionTempDir" ` + | Select-Object -ExpandProperty "PerSessionTempDir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.1" + Task = "(L1) Ensure 'Prevent downloading of enclosures' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.2" + Task = "(L2) Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCloudSearch" ` + | Select-Object -ExpandProperty "AllowCloudSearch" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.3" + Task = "(L1) Ensure 'Allow indexing of encrypted files' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.4" + Task = "(L2) Ensure 'Allow search highlights' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "EnableDynamicContentInWSB" ` + | Select-Object -ExpandProperty "EnableDynamicContentInWSB" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.62.1" + Task = "(L2) Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" ` + -Name "NoGenTicket" ` + | Select-Object -ExpandProperty "NoGenTicket" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.75.2.1 A" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (EnableSmartScreen)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.75.2.1 B" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (ShellSmartScreenLevel)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.79.1" + Task = "(L2) Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowSuggestedAppsInWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowSuggestedAppsInWindowsInkWorkspace" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.79.2" + Task = "(L1) Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Enabled: Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if ($regValue -ne 1 -and $regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.1" + Task = "(L1) Ensure 'Allow user control over installs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.2" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.3" + Task = "(L2) Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.1" + Task = "(L1) Ensure 'Sign-in and lock last interactive user automatically after a restart' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.86.1" + Task = "(L2) Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.86.2" + Task = "(L2) Ensure 'Turn on PowerShell Transcription' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" ` + -Name "EnableTranscripting" ` + | Select-Object -ExpandProperty "EnableTranscripting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.1.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.1.2" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.1.3" + Task = "(L1) Ensure 'Disallow Digest authentication' is set to 'Enabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.2" + Task = "(L2) Ensure 'Allow remote server management through WinRM' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowAutoConfig" ` + | Select-Object -ExpandProperty "AllowAutoConfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.3" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.4" + Task = "(L1) Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1" + Task = "(L2) Ensure 'Allow Remote Shell Access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service\WinRS" ` + -Name "AllowRemoteShellAccess" ` + | Select-Object -ExpandProperty "AllowRemoteShellAccess" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.91.2.1" + Task = "(L1) Ensure 'Prevent users from modifying settings' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection" ` + -Name "DisallowExploitProtectionOverride" ` + | Select-Object -ExpandProperty "DisallowExploitProtectionOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.1.1" + Task = "(L1) Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.1" + Task = "(L1) Ensure 'Configure Automatic Updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.2" + Task = "(L1) Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.1" + Task = "(L1) Ensure 'Manage preview builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "ManagePreviewBuildsPolicyValue" ` + | Select-Object -ExpandProperty "ManagePreviewBuildsPolicyValue" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.2 A" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdates" ` + | Select-Object -ExpandProperty "DeferFeatureUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.2 B" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferFeatureUpdatesPeriodInDays" + + if ($regValue -lt 180 -or $regValue -gt 365) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 180 and x <= 365" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.3 A" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdates" ` + | Select-Object -ExpandProperty "DeferQualityUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.3 B" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferQualityUpdatesPeriodInDays" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.5.1.1" + Task = "(L1) Ensure 'Turn off toast notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.6.6.1.1" + Task = "(L2) Ensure 'Turn off Help Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Assistance\Client\1.0" ` + -Name "NoImplicitFeedback" ` + | Select-Object -ExpandProperty "NoImplicitFeedback" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.5.1" + Task = "(L1) Ensure 'Do not preserve zone information in file attachments' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.5.2" + Task = "(L1) Ensure 'Notify antivirus programs when opening attachments' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "ScanWithAntiVirus" ` + | Select-Object -ExpandProperty "ScanWithAntiVirus" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.1" + Task = "(L1) Ensure 'Configure Windows spotlight on lock screen' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "ConfigureWindowsSpotlight" ` + | Select-Object -ExpandProperty "ConfigureWindowsSpotlight" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.2" + Task = "(L1) Ensure 'Do not suggest third-party content in Windows spotlight' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.3" + Task = "(L2) Ensure 'Do not use diagnostic data for tailored experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableTailoredExperiencesWithDiagnosticData" ` + | Select-Object -ExpandProperty "DisableTailoredExperiencesWithDiagnosticData" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.4" + Task = "(L2) Ensure 'Turn off all Windows spotlight features' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsSpotlightFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsSpotlightFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.5" + Task = "(L1) Ensure 'Turn off Spotlight collection on Desktop' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableSpotlightCollectionOnDesktop" ` + | Select-Object -ExpandProperty "DisableSpotlightCollectionOnDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.26.1" + Task = "(L1) Ensure 'Prevent users from sharing files within their profile.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInplaceSharing" ` + | Select-Object -ExpandProperty "NoInplaceSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.42.1" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled' (AlwaysInstallElevated)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.44.2.1" + Task = "(L2) Ensure 'Prevent Codec Download' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\WindowsMediaPlayer" ` + -Name "PreventCodecDownload" ` + | Select-Object -ExpandProperty "PreventCodecDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#SecurityOptions.ps1 new file mode 100644 index 0000000..59b8d27 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#SecurityOptions.ps1 @@ -0,0 +1,133 @@ +[AuditTest] @{ + Id = "2.3.1.2" + Task = "(L1) Ensure 'Accounts: Guest account status' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.4" + Task = "(L1) Configure 'Accounts: Rename administrator account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption. Expected: ^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.5" + Task = "(L1) Configure 'Accounts: Rename guest account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption. Expected: ^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.1" + Task = "(L1) Ensure 'Network access: Allow anonymous SID/Name translation' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.6" + Task = "(L1) Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["ForceLogoffWhenHourExpire"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 1) { + return @{ + Message = "'ForceLogoffWhenHourExpire' currently set to: $setOption. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#UserRights.ps1 new file mode 100644 index 0000000..1871ea1 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-CIS-3.0.0#UserRights.ps1 @@ -0,0 +1,1979 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + if ($sidAccount.Translate([System.Security.Principal.NTAccount]) -eq "NULL SID") { + return @{ + Account = $null + Sid = $sidAccount.Value + } + } else { + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "2.2.1" + Task = "(L1) Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Authenticated Users, ENTERPRISE DOMAIN CONTROLLERS' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-11" + "S-1-5-32-544" + "S-1-5-9" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.3" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Authenticated Users' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-11" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.4" + Task = "(L1) Ensure 'Act as part of the operating system' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.5" + Task = "(L1) Ensure 'Add workstations to domain' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeMachineAccountPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeMachineAccountPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeMachineAccountPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.6" + Task = "(L1) Ensure 'Adjust memory quotas for a process' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseQuotaPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseQuotaPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseQuotaPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.7" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators, ENTERPRISE DOMAIN CONTROLLERS' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-9" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.8" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.9" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.10" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators, Remote Desktop Users' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.11" + Task = "(L1) Ensure 'Back up files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.12" + Task = "(L1) Ensure 'Change the system time' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemtimePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemtimePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemtimePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.13" + Task = "(L1) Ensure 'Change the time zone' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTimeZonePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTimeZonePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTimeZonePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Ensure 'Create a pagefile' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.15" + Task = "(L1) Ensure 'Create a token object' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.16" + Task = "(L1) Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.17" + Task = "(L1) Ensure 'Create permanent shared objects' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.18" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if($hyperVStatus -ne "Enabled"){ +[AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators [Hyper-V-Feature NOT installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +} +else{ +[AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators, NT VIRTUAL MACHINE\Virtual Machines' [Hyper-V-Feature installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.20" + Task = "(L1) Ensure 'Debug programs' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.21" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.22" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests, Local account and member of Administrators group' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-114" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.23" + Task = "(L1) Ensure 'Deny log on as a batch job' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.24" + Task = "(L1) Ensure 'Deny log on as a service' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyServiceLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.25" + Task = "(L1) Ensure 'Deny log on locally' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.26" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' to include 'Guests' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.27" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' is set to 'Guests, Local account' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-113" + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.28" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.29" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'No One' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.30" + Task = "(L1) Ensure 'Force shutdown from a remote system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +$adfsModule = Get-Module -Name ADFS +if($null -eq $adfsModule){ +[AuditTest] @{ + Id = "2.2.31 A" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE' [ADFS-ROLE NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +} +else{ +[AuditTest] @{ + Id = "2.2.31 B" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE' [ADFS-ROLE installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-80-1321940109-3370001082-3650459431-215109509-2472514016" + "S-1-5-80-2246541699-21809830-3603976364-117610243-975697593" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.32" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if((Get-WindowsFeature -Name web-server).installed -ne $true){ +[AuditTest] @{ + Id = "2.2.33 A" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE' [IIS Role NOT installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +} +else{ +[AuditTest] @{ + Id = "2.2.33 B" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE, IIS_IUSRS' [IIS Role installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-32-568" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.34" + Task = "(L1) Ensure 'Increase scheduling priority' is set to 'Administrators, Window Manager\Window Manager Group'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseBasePriorityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-90-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseBasePriorityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseBasePriorityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.35" + Task = "(L1) Ensure 'Load and unload device drivers' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.36" + Task = "(L1) Ensure 'Lock pages in memory' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.37" + Task = "(L2) Ensure 'Log on as a batch job' is set to 'Administrators' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBatchLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.38" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators' and (when Exchange is running in the environment) 'Exchange Servers' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.39" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.40" + Task = "(L1) Ensure 'Modify an object label' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRelabelPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRelabelPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRelabelPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.41" + Task = "(L1) Ensure 'Modify firmware environment values' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.42" + Task = "(L1) Ensure 'Perform volume maintenance tasks' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.43" + Task = "(L1) Ensure 'Profile single process' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.44" + Task = "(L1) Ensure 'Profile system performance' is set to 'Administrators, NT SERVICE\WdiServiceHost'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemProfilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemProfilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemProfilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.45" + Task = "(L1) Ensure 'Replace a process level token' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAssignPrimaryTokenPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAssignPrimaryTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAssignPrimaryTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.46" + Task = "(L1) Ensure 'Restore files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.47" + Task = "(L1) Ensure 'Shut down the system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.48" + Task = "(L1) Ensure 'Synchronize directory service data' is set to 'No One' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSyncAgentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSyncAgentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSyncAgentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.49" + Task = "(L1) Ensure 'Take ownership of files or other objects' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#AccountPolicies.ps1 new file mode 100644 index 0000000..66c37d2 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#AccountPolicies.ps1 @@ -0,0 +1,252 @@ +[AuditTest] @{ + Id = "V-93141" + Task = "Windows Server 2019 must have the number of allowed bad logon attempts configured to three or less." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 3 -or $setPolicy -eq 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x >= 3 and x != 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93143" + Task = "Windows Server 2019 must have the period of time before the bad logon counter is reset configured to 15 minutes or greater." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x >= 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93145" + Task = "Windows Server 2019 account lockout duration must be configured to 15 minutes or greater." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15) -and ($setPolicy -ne 0)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15 or x == 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93459" + Task = "Windows Server 2019 must have the built-in Windows password complexity policy enabled." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93463" + Task = "Windows Server 2019 minimum password length must be configured to 14 characters." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93465" + Task = "Windows Server 2019 reversible password encryption must be disabled." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93471" + Task = "Windows Server 2019 minimum password age must be configured to at least one day." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -eq 0)) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x != 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93477" + Task = "Windows Server 2019 maximum password age must be configured to 60 days or less." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 60 -or $setPolicy -eq 0)) { + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 60 and x != 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93479" + Task = "Windows Server 2019 password history must be configured to 24 passwords remembered." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#AuditPolicies.ps1 new file mode 100644 index 0000000..40d639d --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#AuditPolicies.ps1 @@ -0,0 +1,1502 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "V-92967 + V-92969" + Task = "Windows Server 2019 must be configured to audit logon successes. Windows Server 2019 must be configured to audit logon failures." + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-92979" + Task = "Windows Server 2019 must be configured to audit Account Management - Security Group Management successes." + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-92981 + V-92983" + Task = "Windows Server 2019 must be configured to audit Account Management - User Account Management successes. Windows Server 2019 must be configured to audit Account Management - User Account Management failures." + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-92985" + Task = "Windows Server 2019 must be configured to audit Account Management - Computer Account Management successes." + Test = { + # Get the audit policy for the subcategory Computer Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Computer Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Computer Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-92987 + V-92989" + Task = "Windows Server 2019 must be configured to audit Logon/Logoff - Account Lockout successes. Windows Server 2019 must be configured to audit Logon/Logoff - Account Lockout failures." + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93089" + Task = "Windows Server 2019 must be configured to audit Account Management - Other Account Management Events successes." + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93091" + Task = "Windows Server 2019 must be configured to audit Detailed Tracking - Process Creation successes." + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93093 + V-93095" + Task = "Windows Server 2019 must be configured to audit Policy Change - Audit Policy Change successes. Windows Server 2019 must be configured to audit Policy Change - Audit Policy Change failures." + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93097" + Task = "Windows Server 2019 must be configured to audit Policy Change - Authentication Policy Change successes." + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93099" + Task = "Windows Server 2019 must be configured to audit Policy Change - Authorization Policy Change successes." + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93101 + V-93103" + Task = "Windows Server 2019 must be configured to audit Privilege Use - Sensitive Privilege Use successes. Windows Server 2019 must be configured to audit Privilege Use - Sensitive Privilege Use failures." + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93105 + V-93107" + Task = "Windows Server 2019 must be configured to audit System - IPsec Driver successes. Windows Server 2019 must be configured to audit System - IPsec Driver failures." + Test = { + # Get the audit policy for the subcategory IPsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "IPsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'IPsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93109 + V-93111" + Task = "Windows Server 2019 must be configured to audit System - Other System Events successes. Windows Server 2019 must be configured to audit System - Other System Events failures." + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93113" + Task = "Windows Server 2019 must be configured to audit System - Security State Change successes." + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93115" + Task = "Windows Server 2019 must be configured to audit System - Security System Extension successes." + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93117 + V-93119" + Task = "Windows Server 2019 must be configured to audit System - System Integrity successes. Windows Server 2019 must be configured to audit System - System Integrity failures." + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93133 + V-93135" + Task = "Windows Server 2019 must be configured to audit DS Access - Directory Service Access successes. Windows Server 2019 must be configured to audit DS Access - Directory Service Access failures." + Test = { + # Get the audit policy for the subcategory Directory Service Access + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Access" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Access'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93137 + V-93139" + Task = "Windows Server 2019 must be configured to audit DS Access - Directory Service Changes successes. Windows Server 2019 must be configured to audit DS Access - Directory Service Changes failures." + Test = { + # Get the audit policy for the subcategory Directory Service Changes + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Changes" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Changes'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93153 + V-93155" + Task = "Windows Server 2019 must be configured to audit Account Logon - Credential Validation successes. Windows Server 2019 must be configured to audit Account Logon - Credential Validation failures." + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93157" + Task = "Windows Server 2019 must be configured to audit Detailed Tracking - Plug and Play Events successes." + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93159" + Task = "Windows Server 2019 must be configured to audit Logon/Logoff - Group Membership successes." + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93161" + Task = "Windows Server 2019 must be configured to audit Logon/Logoff - Special Logon successes." + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93163 + V-93165" + Task = "Windows Server 2019 must be configured to audit Object Access - Other Object Access Events successes. Windows Server 2019 must be configured to audit Object Access - Other Object Access Events failures." + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93167 + V-93169" + Task = "Windows Server 2019 must be configured to audit Object Access - Removable Storage successes. Windows Server 2019 must be configured to audit Object Access - Removable Storage failures." + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-93171" + Task = "Windows Server 2019 must be configured to audit logoff successes." + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#RegistrySettings.ps1 new file mode 100644 index 0000000..ae129c1 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#RegistrySettings.ps1 @@ -0,0 +1,3482 @@ +[AuditTest] @{ + Id = "V-92961" + Task = "Windows Server 2019 machine inactivity limit must be set to 15 minutes or less, locking the system with the screen saver." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-92971" + Task = "Windows Server 2019 Remote Desktop Services must require secure Remote Procedure Call (RPC) communications." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-92973" + Task = "Windows Server 2019 Remote Desktop Services must be configured with the client connection encryption set to High Level." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93045" + Task = "Windows Server 2019 must restrict remote calls to the Security Account Manager (SAM) to Administrators on domain-joined member servers and standalone systems." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictRemoteSAM" ` + | Select-Object -ExpandProperty "RestrictRemoteSAM" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93147" + Task = "Windows Server 2019 required legal notice must be configured to display before console logon." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + if ($regValue -ne "See message text below") { + return @{ + Message = "Registry value is '$regValue'. Expected: See message text below" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93149" + Task = "Windows Server 2019 title for legal banner dialog box must be configured with the appropriate text." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + if ($regValue -ne "See message title options below") { + return @{ + Message = "Registry value is '$regValue'. Expected: See message title options below" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93151" + Task = "Windows Server 2019 must force audit policy subcategory settings to override audit policy category settings." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93173" + Task = "Windows Server 2019 command line data must be included in process creation events." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93175" + Task = "Windows Server 2019 PowerShell script block logging must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93177" + Task = "Windows Server 2019 Application event log size must be configured to 32768 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93179" + Task = "Windows Server 2019 Security event log size must be configured to 196608 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 196608)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93181" + Task = "Windows Server 2019 System event log size must be configured to 32768 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93199" + Task = "Windows Server 2019 must prevent users from changing installation options." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93201" + Task = "Windows Server 2019 must disable the Windows Installer Always install with elevated privileges option." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93233" + Task = "Windows Server 2019 Internet Protocol version 6 (IPv6) source routing must be configured to the highest protection level to prevent IP source routing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93235" + Task = "Windows Server 2019 source routing must be configured to the highest protection level to prevent Internet Protocol (IP) source routing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93237" + Task = "Windows Server 2019 must be configured to prevent Internet Control Message Protocol (ICMP) redirects from overriding Open Shortest Path First (OSPF)-generated routes." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93239" + Task = "Windows Server 2019 insecure logons to an SMB server must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93243" + Task = "Windows Server 2019 must be configured to enable Remote host allows delegation of non-exportable credentials." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93249" + Task = "Windows Server 2019 Early Launch Antimalware, Boot-Start Driver Initialization Policy must prevent boot drivers identified as bad." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if (($regValue -ne 1) -and ($regValue -ne 3) -and ($regValue -ne 8)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 3 or x == 8" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93251" + Task = "Windows Server 2019 group policy objects must be reprocessed even if they have not changed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93253" + Task = "Windows Server 2019 users must be prompted to authenticate when the system wakes from sleep (on battery)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93255" + Task = "Windows Server 2019 users must be prompted to authenticate when the system wakes from sleep (plugged in)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93261" + Task = "Windows Server 2019 Turning off File Explorer heap termination on corruption must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93263" + Task = "Windows Server 2019 File Explorer shell protocol must run in protected mode." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93265" + Task = "Windows Server 2019 must prevent attachments from being downloaded from RSS feeds." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93267" + Task = "Windows Server 2019 users must be notified if a web-based program attempts to install software." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93269" + Task = "Windows Server 2019 must disable automatically signing in the last interactive user after a system-initiated restart." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93273" + Task = "Windows Server 2019 domain controllers must be configured to allow reset of machine account passwords." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RefusePasswordChange" ` + | Select-Object -ExpandProperty "RefusePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93279" + Task = "Windows Server 2019 must prevent local accounts with blank passwords from being used from the network." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93285" + Task = "Windows Server 2019 maximum age for machine account passwords must be configured to 30 days or less." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if (($regValue -gt 30 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93291" + Task = "Windows Server 2019 must not allow anonymous enumeration of Security Account Manager (SAM) accounts." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93293" + Task = "Windows Server 2019 must be configured to prevent anonymous users from having the same permissions as the Everyone group." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93295" + Task = "Windows Server 2019 services using Local System that use Negotiate when reverting to NTLM authentication must use the computer identity instead of authenticating anonymously." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93297" + Task = "Windows Server 2019 must prevent NTLM from falling back to a Null session." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA\MSV1_0" ` + -Name "allownullsessionfallback" ` + | Select-Object -ExpandProperty "allownullsessionfallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93299" + Task = "Windows Server 2019 must prevent PKU2U authentication using online identities." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93301" + Task = "Windows Server 2019 LAN Manager authentication level must be configured to send NTLMv2 response only and to refuse LM and NTLM." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93303" + Task = "Windows Server 2019 must be configured to at least negotiate signing for LDAP client signing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93305" + Task = "Windows Server 2019 session security for NTLM SSP-based clients must be configured to require NTLMv2 session security and 128-bit encryption." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93307" + Task = "Windows Server 2019 session security for NTLM SSP-based servers must be configured to require NTLMv2 session security and 128-bit encryption." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93309" + Task = "Windows Server 2019 default permissions of global system objects must be strengthened." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93311" + Task = "Windows Server 2019 must preserve zone information when saving attachments." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93373" + Task = "Windows Server 2019 Autoplay must be turned off for non-volume devices." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93375" + Task = "Windows Server 2019 default AutoRun behavior must be configured to prevent AutoRun commands." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93377" + Task = "Windows Server 2019 AutoPlay must be disabled for all drives." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93393" + Task = "Windows Server 2019 must have the Server Message Block (SMB) v1 protocol disabled on the SMB server." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93395" + Task = "Windows Server 2019 must have the Server Message Block (SMB) v1 protocol disabled on the SMB client." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93399" + Task = "Windows Server 2019 must prevent the display of slide shows on the lock screen." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93401" + Task = "Windows Server 2019 must have WDigest Authentication disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Wdigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93403" + Task = "Windows Server 2019 downloading print driver packages over HTTP must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93405" + Task = "Windows Server 2019 printing over HTTP must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93407" + Task = "Windows Server 2019 network selection user interface (UI) must not be displayed on the logon screen." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93409" + Task = "Windows Server 2019 Application Compatibility Program Inventory must be prevented from collecting data and sending the information to Microsoft." + Test = { + try { + $status = get-service -name pcasvc -ErrorAction Stop + if($status.Status -ne "Stopped"){ + return @{ + Message = "Compliant - AppCompat Service is disabled (no inventory data will be collected)." + Status = "True" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppCompat" ` + -Name "DisableInventory" ` + | Select-Object -ExpandProperty "DisableInventory" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + catch [System.SystemException]{ + return @{ + Message = "Service not found!" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93411" + Task = "Windows Server 2019 Windows Defender SmartScreen must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93413" + Task = "Windows Server 2019 must disable Basic authentication for RSS feeds over HTTP." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "AllowBasicAuthInClear" ` + | Select-Object -ExpandProperty "AllowBasicAuthInClear" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93415" + Task = "Windows Server 2019 must prevent Indexing of encrypted files." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93419" + Task = "Windows Server 2019 local users on domain-joined member servers must not be enumerated." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93425" + Task = "Windows Server 2019 must not save passwords in the Remote Desktop Client." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93427" + Task = "Windows Server 2019 Remote Desktop Services must always prompt a client for passwords upon connection." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93429" + Task = "Windows Server 2019 Windows Remote Management (WinRM) service must not store RunAs credentials." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93431" + Task = "Windows Server 2019 User Account Control approval mode for the built-in Administrator must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93433" + Task = "Windows Server 2019 User Account Control must automatically deny standard user requests for elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93435" + Task = "Windows Server 2019 User Account Control must run all administrators in Admin Approval Mode, enabling UAC." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93453" + Task = "Windows Server 2019 must restrict unauthenticated Remote Procedure Call (RPC) clients from connecting to the RPC server on domain-joined member servers and standalone systems." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Standalone Workstation", "Member Workstation", "Standalone Server", "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93455" + Task = "Windows Server 2019 computer account password must not be prevented from being reset." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93467" + Task = "Windows Server 2019 must be configured to prevent the storage of the LAN Manager hash of passwords." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93469" + Task = "Windows Server 2019 unencrypted passwords must not be sent to third-party Server Message Block (SMB) servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93493" + Task = "Windows Server 2019 users must be required to enter a password to access private keys stored on the computer." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography" ` + -Name "ForceKeyProtection" ` + | Select-Object -ExpandProperty "ForceKeyProtection" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93495" + Task = "Windows Server 2019 Kerberos encryption types must be configured to prevent the use of DES and RC4 encryption suites." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93499" + Task = "Windows Server 2019 Windows Remote Management (WinRM) client must not allow unencrypted traffic." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93501" + Task = "Windows Server 2019 Windows Remote Management (WinRM) service must not allow unencrypted traffic." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93503" + Task = "Windows Server 2019 Windows Remote Management (WinRM) client must not use Basic authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93505" + Task = "Windows Server 2019 Windows Remote Management (WinRM) client must not use Digest authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93507" + Task = "Windows Server 2019 Windows Remote Management (WinRM) service must not use Basic authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93511" + Task = "Windows Server 2019 must be configured to use FIPS-compliant algorithms for encryption, hashing, and signing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93517" + Task = "Windows Server 2019 administrator accounts must not be enumerated during elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93519" + Task = "Windows Server 2019 local administrator accounts must have their privileged token filtered to prevent elevated privileges from being used over the network on domain-joined member servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93521" + Task = "Windows Server 2019 UIAccess applications must not be allowed to prompt for elevation without using the secure desktop." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableUIADesktopToggle" ` + | Select-Object -ExpandProperty "EnableUIADesktopToggle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93525" + Task = "Windows Server 2019 User Account Control must be configured to detect application installations and prompt for elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93527" + Task = "Windows Server 2019 User Account Control (UAC) must only elevate UIAccess applications that are installed in secure locations." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93529" + Task = "Windows Server 2019 User Account Control (UAC) must virtualize file and registry write failures to per-user locations." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93533" + Task = "Windows Server 2019 Remote Desktop Services must prevent drive redirection." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93537" + Task = "Windows Server 2019 must not allow anonymous enumeration of shares." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93539" + Task = "Windows Server 2019 must restrict anonymous access to Named Pipes and Shares." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93541" + Task = "Windows Server 2019 must be configured to ignore NetBIOS name release requests except from WINS servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NoNameReleaseOnDemand" ` + | Select-Object -ExpandProperty "NoNameReleaseOnDemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93545" + Task = "Windows Server 2019 domain controllers must require LDAP access signing." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LDAPServerIntegrity" ` + | Select-Object -ExpandProperty "LDAPServerIntegrity" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93547" + Task = "Windows Server 2019 setting Domain member: Digitally encrypt or sign secure channel data (always) must be configured to Enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93549" + Task = "Windows Server 2019 setting Domain member: Digitally encrypt secure channel data (when possible) must be configured to enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93551" + Task = "Windows Server 2019 setting Domain member: Digitally sign secure channel data (when possible) must be configured to Enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93553" + Task = "Windows Server 2019 must be configured to require a strong session key." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93555" + Task = "Windows Server 2019 setting Microsoft network client: Digitally sign communications (always) must be configured to Enabled." + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-93557" + Task = "Windows Server 2019 setting Microsoft network client: Digitally sign communications (if server agrees) must be configured to Enabled." + Test = { + try { + if((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-93559" + Task = "Windows Server 2019 setting Microsoft network server: Digitally sign communications (always) must be configured to Enabled." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-93561" + Task = "Windows Server 2019 setting Microsoft network server: Digitally sign communications (if client agrees) must be configured to Enabled." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-93563" + Task = "Windows Server 2019 Explorer Data Execution Prevention must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#SecurityOptions.ps1 new file mode 100644 index 0000000..8212e96 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-DISA-V1R5#SecurityOptions.ps1 @@ -0,0 +1,104 @@ +[AuditTest] @{ + Id = "V-93281" + Task = "Windows Server 2019 built-in administrator account must be renamed." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?!.*\bAdministrator\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93283" + Task = "Windows Server 2019 built-in guest account must be renamed." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93289" + Task = "Windows Server 2019 must not allow anonymous SID/Name translation." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-93497" + Task = "Windows Server 2019 must have the built-in guest account disabled." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#AccountPolicies.ps1 new file mode 100644 index 0000000..dab2b4d --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#AccountPolicies.ps1 @@ -0,0 +1,252 @@ +[AuditTest] @{ + Id = "AccountPolicy-001" + Task = "Ensure 'MinimumPasswordAge' is set to '1'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-002" + Task = "Ensure 'MaximumPasswordAge' is set to '60'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 60) { + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: 60" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-003" + Task = "Ensure 'MinimumPasswordLength' is set to '14'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 14) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-004" + Task = "Ensure 'PasswordComplexity' is set to '1'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-005" + Task = "Ensure 'PasswordHistorySize' is set to '24'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-006" + Task = "Ensure 'LockoutBadCount' is set to '10'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 10) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: 10" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-007" + Task = "Ensure 'ResetLockoutCount' is set to '15'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 15) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-008" + Task = "Ensure 'LockoutDuration' is set to '15'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 15) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: 15" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-009" + Task = "Ensure 'ClearTextPassword' is set to '0'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#AuditPolicies.ps1 new file mode 100644 index 0000000..002cdb7 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#AuditPolicies.ps1 @@ -0,0 +1,1388 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "AuditPolicy-001" + Task = "Ensure 'Credential Validation' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-002" + Task = "Ensure 'Security Group Management' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-003" + Task = "Ensure 'User Account Management' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-004" + Task = "Ensure 'PNP Activity' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-005" + Task = "Ensure 'Process Creation' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-006" + Task = "Ensure 'Account Lockout' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-007" + Task = "Ensure 'Group Membership' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-008" + Task = "Ensure 'Logon' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-009" + Task = "Ensure 'Other Logon/Logoff Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-010" + Task = "Ensure 'Special Logon' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-011" + Task = "Ensure 'Detailed File Share' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-012" + Task = "Ensure 'File Share' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-013" + Task = "Ensure 'Other Object Access Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-014" + Task = "Ensure 'Removable Storage' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-015" + Task = "Ensure 'Audit Policy Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-016" + Task = "Ensure 'Authentication Policy Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-017" + Task = "Ensure 'MPSSVC Rule-Level Policy Change' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory MPSSVC Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "MPSSVC Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'MPSSVC Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-018" + Task = "Ensure 'Other Policy Change Events' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-019" + Task = "Ensure 'Sensitive Privilege Use' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-020" + Task = "Ensure 'Other System Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-021" + Task = "Ensure 'Security State Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-022" + Task = "Ensure 'Security System Extension' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-023" + Task = "Ensure 'System Integrity' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#RegistrySettings.ps1 new file mode 100644 index 0000000..749400a --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#RegistrySettings.ps1 @@ -0,0 +1,9235 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "Registry-001" + Task = "Ensure 'Remove `"Run this time`" button for outdated ActiveX controls in Internet Explorer ' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "RunThisTimeEnabled" ` + | Select-Object -ExpandProperty "RunThisTimeEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-002" + Task = "Ensure 'Turn off blocking of outdated ActiveX controls for Internet Explorer' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "VersionCheckEnabled" ` + | Select-Object -ExpandProperty "VersionCheckEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-003" + Task = "Ensure 'Allow software to run or install even if the signature is invalid' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "RunInvalidSignatures" ` + | Select-Object -ExpandProperty "RunInvalidSignatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-004" + Task = "Set registry value 'CheckExeSignatures' to yes." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "CheckExeSignatures" ` + | Select-Object -ExpandProperty "CheckExeSignatures" + + if ($regValue -ne "yes") { + return @{ + Message = "Registry value is '$regValue'. Expected: yes" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-005" + Task = "Ensure 'Turn on 64-bit tab processes when running in Enhanced Protected Mode on 64-bit versions of Windows' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation64Bit" ` + | Select-Object -ExpandProperty "Isolation64Bit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-006" + Task = "Ensure 'Do not allow ActiveX controls to run in Protected Mode when Enhanced Protected Mode is enabled' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "DisableEPMCompat" ` + | Select-Object -ExpandProperty "DisableEPMCompat" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-007" + Task = "Set registry value 'Isolation' to PMEM." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation" ` + | Select-Object -ExpandProperty "Isolation" + + if ($regValue -ne "PMEM") { + return @{ + Message = "Registry value is '$regValue'. Expected: PMEM" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-008" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_DISABLE_MK_PROTOCOL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-009" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_DISABLE_MK_PROTOCOL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-010" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_DISABLE_MK_PROTOCOL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-011" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_MIME_HANDLING)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-012" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_MIME_HANDLING)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-013" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_MIME_HANDLING)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-014" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_MIME_SNIFFING)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-015" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_MIME_SNIFFING)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-016" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_MIME_SNIFFING)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-017" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_RESTRICT_ACTIVEXINSTALL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-018" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_RESTRICT_ACTIVEXINSTALL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-019" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_RESTRICT_ACTIVEXINSTALL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-020" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_RESTRICT_FILEDOWNLOAD)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-021" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_RESTRICT_FILEDOWNLOAD)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-022" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_RESTRICT_FILEDOWNLOAD)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-023" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_SECURITYBAND)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-024" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_SECURITYBAND)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-025" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_SECURITYBAND)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-026" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_WINDOW_RESTRICTIONS)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-027" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_WINDOW_RESTRICTIONS)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-028" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_WINDOW_RESTRICTIONS)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-029" + Task = "Set registry value '(Reserved)' to 1. (FEATURE_ZONE_ELEVATION)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-030" + Task = "Set registry value 'explorer.exe' to 1. (FEATURE_ZONE_ELEVATION)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-031" + Task = "Set registry value 'iexplore.exe' to 1. (FEATURE_ZONE_ELEVATION)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-032" + Task = "Set registry value 'PreventOverrideAppRepUnknown' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverrideAppRepUnknown" ` + | Select-Object -ExpandProperty "PreventOverrideAppRepUnknown" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-033" + Task = "Set registry value 'PreventOverride' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-034" + Task = "Ensure 'Prevent managing SmartScreen Filter' is set to 'On'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-035" + Task = "Set registry value 'NoCrashDetection' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Restrictions" ` + -Name "NoCrashDetection" ` + | Select-Object -ExpandProperty "NoCrashDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-036" + Task = "Ensure 'Turn off the Security Settings Check feature' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security" ` + -Name "DisableSecuritySettingsCheck" ` + | Select-Object -ExpandProperty "DisableSecuritySettingsCheck" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-037" + Task = "Ensure 'Prevent per-user installation of ActiveX controls' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security\ActiveX" ` + -Name "BlockNonAdminActiveXInstall" ` + | Select-Object -ExpandProperty "BlockNonAdminActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-038" + Task = "Ensure 'Specify use of ActiveX Installer Service for installation of ActiveX controls' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AxInstaller" ` + -Name "OnlyUseAXISForActiveXInstall" ` + | Select-Object -ExpandProperty "OnlyUseAXISForActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-039" + Task = "Set registry value 'Security_zones_map_edit' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_zones_map_edit" ` + | Select-Object -ExpandProperty "Security_zones_map_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-040" + Task = "Set registry value 'Security_options_edit' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_options_edit" ` + | Select-Object -ExpandProperty "Security_options_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-041" + Task = "Set registry value 'Security_HKLM_only' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_HKLM_only" ` + | Select-Object -ExpandProperty "Security_HKLM_only" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-042" + Task = "Ensure 'Check for server certificate revocation' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "CertificateRevocation" ` + | Select-Object -ExpandProperty "CertificateRevocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-043" + Task = "Ensure 'Prevent ignoring certificate errors' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "PreventIgnoreCertErrors" ` + | Select-Object -ExpandProperty "PreventIgnoreCertErrors" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-044" + Task = "Set registry value 'WarnOnBadCertRecving' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "WarnOnBadCertRecving" ` + | Select-Object -ExpandProperty "WarnOnBadCertRecving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-045" + Task = "Ensure 'Allow fallback to SSL 3.0 (Internet Explorer)' is set to 'No Sites'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "EnableSSL3Fallback" ` + | Select-Object -ExpandProperty "EnableSSL3Fallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-046" + Task = "Ensure 'Turn off encryption support' is set to 'Use TLS 1.1 and TLS 1.2'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "SecureProtocols" ` + | Select-Object -ExpandProperty "SecureProtocols" + + if ($regValue -ne 2560) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2560" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-047" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Lockdown_Zones/0)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-048" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Lockdown_Zones/1)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-049" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Lockdown_Zones/2)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-050" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Lockdown_Zones\3]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\3" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-051" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Lockdown_Zones\4]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-052" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Lockdown_Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-053" + Task = "Ensure 'Intranet Sites: Include all network paths (UNCs)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap" ` + -Name "UNCAsIntranet" ` + | Select-Object -ExpandProperty "UNCAsIntranet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-054" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Zones/0)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-055" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'. (Zones/0)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-056" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'. (Zones/1)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-057" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'. (Zones/1)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-058" + Task = "Ensure 'Java permissions' is set to 'High safety'. (Zones/1)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-059" + Task = "Ensure 'Java permissions' is set to 'High safety'. (Zones/2)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-060" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'. (Zones/2)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-061" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'. (Zones/2)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-062" + Task = "Ensure 'Run .NET Framework-reliant components signed with Authenticode' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-063" + Task = "Ensure 'Allow script-initiated windows without size or position constraints' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-064" + Task = "Ensure 'Allow drag and drop or copy and paste files' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-065" + Task = "Ensure 'Include local path when user is uploading files to a server' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-066" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-067" + Task = "Ensure 'Access data sources across domains' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-068" + Task = "Ensure 'Launching applications and files in an IFRAME' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-069" + Task = "Ensure 'Automatic prompting for file downloads' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-070" + Task = "Ensure 'Allow scriptlets' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-071" + Task = "Ensure 'Allow scripting of Internet Explorer WebBrowser controls' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-072" + Task = "Ensure 'Use Pop-up Blocker' is set to 'Enable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-073" + Task = "Ensure 'Turn on Protected Mode' is set to 'Enable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-074" + Task = "Ensure 'Allow updates to status bar via script' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-075" + Task = "Ensure 'Userdata persistence' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-076" + Task = "Ensure 'Allow loading of XAML files' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-077" + Task = "Ensure 'Run .NET Framework-reliant components not signed with Authenticode' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-078" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-079" + Task = "Ensure 'Download signed ActiveX controls' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-080" + Task = "Ensure 'Logon options' is set to 'Prompt for user name and password'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-081" + Task = "Ensure 'Enable dragging of content from different domains within a window' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-082" + Task = "Ensure 'Download unsigned ActiveX controls' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-083" + Task = "Ensure 'Allow only approved domains to use ActiveX controls without prompt' is set to 'Enable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-084" + Task = "Ensure 'Allow cut, copy or paste operations from the clipboard via script' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-085" + Task = "Ensure 'Turn on Cross-Site Scripting Filter' is set to 'Enable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-086" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-087" + Task = "Ensure 'Navigate windows and frames across different domains' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-088" + Task = "Ensure 'Enable dragging of content from different domains across windows' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-089" + Task = "Ensure 'Web sites in less privileged Web content zones can navigate into this zone' is set to 'Disable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-090" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Zones\3]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-091" + Task = "Ensure 'Show security warning for potentially unsafe files' is set to 'Prompt'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-092" + Task = "Ensure 'Allow only approved domains to use the TDC ActiveX control' is set to 'Enable'. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120c" ` + | Select-Object -ExpandProperty "120c" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-093" + Task = "Set registry value '140C' to 3. (Zones/3)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "140C" ` + | Select-Object -ExpandProperty "140C" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-094" + Task = "Ensure 'Allow META REFRESH' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1608" ` + | Select-Object -ExpandProperty "1608" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-095" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-096" + Task = "Ensure 'Download signed ActiveX controls' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-097" + Task = "Ensure 'Navigate windows and frames across different domains' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-098" + Task = "Ensure 'Allow only approved domains to use ActiveX controls without prompt' is set to 'Enable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-099" + Task = "Ensure 'Use Pop-up Blocker' is set to 'Enable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-100" + Task = "Ensure 'Download unsigned ActiveX controls' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-101" + Task = "Ensure 'Userdata persistence' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-102" + Task = "Ensure 'Allow cut, copy or paste operations from the clipboard via script' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-103" + Task = "Ensure 'Include local path when user is uploading files to a server' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-104" + Task = "Ensure 'Access data sources across domains' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-105" + Task = "Ensure 'Allow script-initiated windows without size or position constraints' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-106" + Task = "Ensure 'Run .NET Framework-reliant components not signed with Authenticode' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-107" + Task = "Ensure 'Automatic prompting for file downloads' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-108" + Task = "Ensure 'Allow binary and script behaviors' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2000" ` + | Select-Object -ExpandProperty "2000" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-109" + Task = "Ensure 'Scripting of Java applets' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1402" ` + | Select-Object -ExpandProperty "1402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-110" + Task = "Ensure 'Allow file downloads' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1803" ` + | Select-Object -ExpandProperty "1803" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-111" + Task = "Ensure 'Allow loading of XAML files' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-112" + Task = "Ensure 'Allow active scripting' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1400" ` + | Select-Object -ExpandProperty "1400" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-113" + Task = "Ensure 'Logon options' is set to 'Anonymous logon'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-114" + Task = "Ensure 'Run .NET Framework-reliant components signed with Authenticode' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-115" + Task = "Ensure 'Turn on Protected Mode' is set to 'Enable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-116" + Task = "Ensure 'Turn on Cross-Site Scripting Filter' is set to 'Enable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-117" + Task = "Ensure 'Java permissions' is set to 'Disable Java'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-118" + Task = "Ensure 'Allow scriptlets' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-119" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-120" + Task = "Ensure 'Allow scripting of Internet Explorer WebBrowser controls' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-121" + Task = "Ensure 'Enable dragging of content from different domains within a window' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-122" + Task = "Ensure 'Allow drag and drop or copy and paste files' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-123" + Task = "Ensure 'Allow updates to status bar via script' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-124" + Task = "Ensure 'Enable dragging of content from different domains across windows' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-125" + Task = "Ensure 'Script ActiveX controls marked safe for scripting' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1405" ` + | Select-Object -ExpandProperty "1405" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-126" + Task = "Ensure 'Web sites in less privileged Web content zones can navigate into this zone' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-127" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Zones\4]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-128" + Task = "Ensure 'Run ActiveX controls and plugins' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1200" ` + | Select-Object -ExpandProperty "1200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-129" + Task = "Ensure 'Launching applications and files in an IFRAME' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-130" + Task = "Ensure 'Show security warning for potentially unsafe files' is set to 'Disable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-131" + Task = "Ensure 'Allow only approved domains to use the TDC ActiveX control' is set to 'Enable'. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120c" ` + | Select-Object -ExpandProperty "120c" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-132" + Task = "Set registry value '140C' to 3. (Zones/4)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "140C" ` + | Select-Object -ExpandProperty "140C" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-133" + Task = "Set registry value 'PUAProtection' to 1." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-134" + Task = "Ensure 'Turn on behavior monitoring' is set to 'Enabled'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-135" + Task = "Ensure 'Scan removable drives' is set to 'Enabled'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-136" + Task = "Ensure 'Turn on e-mail scanning' is set to 'Enabled'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-137" + Task = "Ensure 'Send file samples when further analysis is required' is set to 'Send safe samples'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SubmitSamplesConsent" ` + | Select-Object -ExpandProperty "SubmitSamplesConsent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-138" + Task = "Ensure 'Join Microsoft MAPS' is set to 'Advanced MAPS'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-139" + Task = "Set registry value 'ExploitGuard_ASR_Rules' to 1." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-140" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from injecting code into other processes)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-141" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from creating executable content)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-142" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from creating child processes)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-143" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Win32 API calls from Office macro)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-144" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block execution of potentially obfuscated scripts)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-145" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block JavaScript or VBScript from launching downloaded executable content)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-146" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block executable content from email client and webmail)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-147" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block credential stealing from the Windows local security authority subsystem (lsass.exe))" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-148" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block untrusted and unsigned processes that run from USB)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-149" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office communication application from creating child processes)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-150" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Adobe Reader from creating child processes)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-151" + Task = "Set registry value 'EnableNetworkProtection' to 1." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-161" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-162" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Secure Boot'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if ($regValue -eq 3) { + return @{ + Message = "Set to 'Secure Boot and DMA Protection' which is more secure." + Status = "True" + } + } + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-163" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled with UEFI lock'. (HypervisorEnforcedCodeIntegrity)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-164" + Task = "Set registry value 'HVCIMATRequired' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HVCIMATRequired" ` + | Select-Object -ExpandProperty "HVCIMATRequired" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-165" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled with UEFI lock'. (LsaCfgFlags)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-166" + Task = "Set registry value 'ConfigureSystemGuardLaunch' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureSystemGuardLaunch" ` + | Select-Object -ExpandProperty "ConfigureSystemGuardLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-167" + Task = "Ensure 'Turn off Autoplay' is set to 'All drives'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-168" + Task = "Ensure 'Set the default behavior for AutoRun' is set to 'Do not execute any autorun commands'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-169" + Task = "Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-170" + Task = "Set registry value 'LocalAccountTokenFilterPolicy' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-171" + Task = "Set registry value 'AllowEncryptionOracle' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-172" + Task = "Set registry value 'EnhancedAntiSpoofing' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-173" + Task = "Ensure 'Prevent downloading of enclosures' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-174" + Task = "Set registry value 'AllowProtectedCreds' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-175" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '32768'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-176" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '196608'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-177" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '32768'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-178" + Task = "Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-179" + Task = "Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-180" + Task = "Ensure 'Turn off heap termination on corruption' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-181" + Task = "Ensure 'Configure registry policy processing' is set to '0'. (NoBackgroundPolicy)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-182" + Task = "Ensure 'Configure registry policy processing' is set to '0'. (NoGPOListChanges)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-183" + Task = "Set registry value 'AlwaysInstallElevated' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-184" + Task = "Ensure 'Allow user control over installs' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-185" + Task = "Set registry value 'DeviceEnumerationPolicy' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-186" + Task = "Ensure 'Enable insecure guest logons' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-187" + Task = "Set registry value '\\*\SYSVOL' to RequireMutualAuthentication=1, RequireIntegrity=1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-188" + Task = "Set registry value '\\*\NETLOGON' to RequireMutualAuthentication=1, RequireIntegrity=1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-189" + Task = "Set registry value 'NoLockScreenCamera' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-190" + Task = "Set registry value 'NoLockScreenSlideshow' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-191" + Task = "Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-192" + Task = "Ensure 'Turn on PowerShell Script Block Logging' is set to 'disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockInvocationLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockInvocationLogging" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-193" + Task = "Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-194" + Task = "Ensure 'Configure Windows SmartScreen' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-195" + Task = "Set registry value 'ShellSmartScreenLevel' to Block." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-196" + Task = "Set registry value 'AllowIndexingEncryptedStoresOrItems' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-197" + Task = "Ensure 'Allow Basic authentication' is set to 'Disabled'. (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-198" + Task = "Ensure 'Allow unencrypted traffic' is set to 'Disabled'. (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-199" + Task = "Ensure 'Disallow Digest authentication' is set to 'Enabled'. (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-200" + Task = "Ensure 'Allow Basic authentication' is set to 'Disabled'. (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-201" + Task = "Ensure 'Allow unencrypted traffic' is set to 'Disabled'. (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-202" + Task = "Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'. (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-203" + Task = "Ensure 'Restrict Unauthenticated RPC clients' is set to 'Authenticated'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-204" + Task = "Set registry value 'DisablePasswordSaving' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-205" + Task = "Set registry value 'fDisableCdm' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-206" + Task = "Set registry value 'fPromptForPassword' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-207" + Task = "Set registry value 'fEncryptRPCTraffic' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-208" + Task = "Set registry value 'MinEncryptionLevel' to 3." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-210" + Task = "Set registry value 'DefaultOutboundAction' to 0. (DomainProfile)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-211" + Task = "Set registry value 'DefaultInboundAction' to 1. (DomainProfile)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-212" + Task = "Set registry value 'EnableFirewall' to 1. (DomainProfile)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-213" + Task = "Set registry value 'EnableFirewall' to 1. (PrivateProfile)" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-214" + Task = "Set registry value 'DefaultInboundAction' to 1. (PrivateProfile)" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-215" + Task = "Set registry value 'DefaultOutboundAction' to 0. (PrivateProfile)" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-216" + Task = "Set registry value 'EnableFirewall' to 1. (PublicProfile)" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-217" + Task = "Set registry value 'DefaultOutboundAction' to 0. (PublicProfile)" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-218" + Task = "Set registry value 'DefaultInboundAction' to 1. (PublicProfile)" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-219" + Task = "Ensure 'Allow Windows Ink Workspace' is set to 'On, but disallow access above lock'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-220" + Task = "Set registry value 'AdmPwdEnabled' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft Services\AdmPwd" ` + -Name "AdmPwdEnabled" ` + | Select-Object -ExpandProperty "AdmPwdEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-221" + Task = "Ensure 'WDigest Authentication (disabling may require KB2871997)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-222" + Task = "Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-223" + Task = "Set registry value 'DriverLoadPolicy' to 3." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-224" + Task = "Ensure 'Configure SMB v1 server' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-225" + Task = "Ensure 'Configure SMB v1 client driver' is set to 'Disable driver (recommended)'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MrxSmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-226" + Task = "Set registry value 'NoNameReleaseOnDemand' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NoNameReleaseOnDemand" ` + | Select-Object -ExpandProperty "NoNameReleaseOnDemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-227" + Task = "Set registry value 'EnableICMPRedirect' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-228" + Task = "Set registry value 'DisableIPSourceRouting' to 2. (Tcpip)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-229" + Task = "Set registry value 'DisableIPSourceRouting' to 2. (Tcpip6)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-230" + Task = "Set registry value 'allownullsessionfallback' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "allownullsessionfallback" ` + | Select-Object -ExpandProperty "allownullsessionfallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-231" + Task = "Set registry value 'InactivityTimeoutSecs' to 900." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if ($regValue -ne 900) { + return @{ + Message = "Registry value is '$regValue'. Expected: 900" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-232" + Task = "Set registry value 'ScRemoveOption' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-233" + Task = "Set registry value 'SCENoApplyLegacyAuditPolicy' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-234" + Task = "Set registry value 'EnableVirtualization' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-235" + Task = "Set registry value 'FilterAdministratorToken' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-236" + Task = "Set registry value 'EnableLUA' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-237" + Task = "Set registry value 'EnableInstallerDetection' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-238" + Task = "Set registry value 'ConsentPromptBehaviorAdmin' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-239" + Task = "Set registry value 'ConsentPromptBehaviorUser' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-240" + Task = "Set registry value 'EnableSecureUIAPaths' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-241" + Task = "Set registry value 'LDAPClientIntegrity' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-242" + Task = "Set registry value 'LmCompatibilityLevel' to 5." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-243" + Task = "Set registry value 'NTLMMinClientSec' to 537395200." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-244" + Task = "Set registry value 'sealsecurechannel' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "sealsecurechannel" ` + | Select-Object -ExpandProperty "sealsecurechannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-245" + Task = "Set registry value 'NTLMMinServerSec' to 537395200." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-246" + Task = "Set registry value 'requiresignorseal' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "requiresignorseal" ` + | Select-Object -ExpandProperty "requiresignorseal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-247" + Task = "Set registry value 'signsecurechannel' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "signsecurechannel" ` + | Select-Object -ExpandProperty "signsecurechannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-248" + Task = "Set registry value 'RequireSecuritySignature' to 1." + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Registry-249" + Task = "Set registry value 'requiresecuritysignature' to 1." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Registry-250" + Task = "Set registry value 'requirestrongkey' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "requirestrongkey" ` + | Select-Object -ExpandProperty "requirestrongkey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-251" + Task = "Set registry value 'RestrictAnonymousSAM' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-252" + Task = "Set registry value 'RestrictNullSessAccess' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-253" + Task = "Set registry value 'RestrictAnonymous' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-254" + Task = "Set registry value 'ProtectionMode' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-255" + Task = "Set registry value 'LimitBlankPasswordUse' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-256" + Task = "Set registry value 'maximumpasswordage' to 30." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "maximumpasswordage" ` + | Select-Object -ExpandProperty "maximumpasswordage" + + if ($regValue -ne 30) { + return @{ + Message = "Registry value is '$regValue'. Expected: 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-257" + Task = "Set registry value 'disablepasswordchange' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "disablepasswordchange" ` + | Select-Object -ExpandProperty "disablepasswordchange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-258" + Task = "Set registry value 'NoLMHash' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-259" + Task = "Set registry value 'EnablePlainTextPassword' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-260" + Task = "Set registry value 'RestrictRemoteSAM' to O:BAG:BAD:(A;;RC;;;BA)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictRemoteSAM" ` + | Select-Object -ExpandProperty "RestrictRemoteSAM" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#SecurityOptions.ps1 new file mode 100644 index 0000000..60a1b0e --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#SecurityOptions.ps1 @@ -0,0 +1,52 @@ +[AuditTest] @{ + Id = "SecurityOption-261" + Task = "Ensure 'LSAAnonymousNameLookup' is set to '0'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SecurityOption-262" + Task = "Ensure 'EnableGuestAccount' is set to '0'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#UserRights.ps1 new file mode 100644 index 0000000..9b251b5 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2019-Microsoft-FINAL#UserRights.ps1 @@ -0,0 +1,897 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + if ($sidAccount.Translate([System.Security.Principal.NTAccount]) -eq "NULL SID") { + return @{ + Account = $null + Sid = $sidAccount.Value + } + } else { + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "UserRight-001" + Task = "Ensure 'SeSecurityPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-002" + Task = "Ensure 'SeCreateTokenPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-003" + Task = "Ensure 'SeTrustedCredManAccessPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-004" + Task = "Ensure 'SeCreatePagefilePrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-005" + Task = "Ensure 'SeRemoteShutdownPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-006" + Task = "Ensure 'SeLoadDriverPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-007" + Task = "Ensure 'SeRestorePrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-008" + Task = "Ensure 'SeCreateGlobalPrivilege' is set to 'S-1-5-32-544, S-1-5-6, S-1-5-19, S-1-5-20'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-6" + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-009" + Task = "Ensure 'SeManageVolumePrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-010" + Task = "Ensure 'SeInteractiveLogonRight' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-011" + Task = "Ensure 'SeEnableDelegationPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-012" + Task = "Ensure 'SeCreatePermanentPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-013" + Task = "Ensure 'SeDebugPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-014" + Task = "Ensure 'SeProfileSingleProcessPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-015" + Task = "Ensure 'SeBackupPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-016" + Task = "Ensure 'SeNetworkLogonRight' is set to 'S-1-5-32-544, S-1-5-11'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-11" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-017" + Task = "Ensure 'SeDenyNetworkLogonRight' is set to 'S-1-5-114'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "MemberServer" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-114" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-018" + Task = "Ensure 'SeImpersonatePrivilege' is set to 'S-1-5-32-544, S-1-5-6, S-1-5-19, S-1-5-20'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-6" + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-019" + Task = "Ensure 'SeSystemEnvironmentPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-020" + Task = "Ensure 'SeLockMemoryPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-021" + Task = "Ensure 'SeTcbPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-022" + Task = "Ensure 'SeTakeOwnershipPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-023" + Task = "Ensure 'SeDenyRemoteInteractiveLogonRight' is set to 'S-1-5-113'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "MemberServer" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#AccountPolicies.ps1 new file mode 100644 index 0000000..f91cbf1 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#AccountPolicies.ps1 @@ -0,0 +1,283 @@ +[AuditTest] @{ + Id = "1.1.1" + Task = "(L1) Ensure 'Enforce password history' is set to '24 or more password(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "(L1) Ensure 'Maximum password age' is set to '365 or fewer days, but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 365 -or $setPolicy -le 0)) { + if($setPolicy -eq -1){ #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 365 days and x > 0 days" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "(L1) Ensure 'Minimum password age' is set to '1 or more day(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 1)) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1 days" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "(L1) Ensure 'Minimum password length' is set to '14 or more character(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.5" + Task = "(L1) Ensure 'Password must meet complexity requirements' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.7" + Task = "(L1) Ensure 'Store passwords using reversible encryption' is set to 'Disabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "(L1) Ensure 'Account lockout duration' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "(L1) Ensure 'Account lockout threshold' is set to '5 or fewer invalid logon attempt(s), but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 5 -or $setPolicy -le 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 5 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.3" + Task = "(L1) Ensure 'Allow Administrator account lockout' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["AllowAdministratorLockout"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'AllowAdministratorLockout' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.4" + Task = "(L1) Ensure 'Reset account lockout counter after' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x >= 15 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#AuditPolicies.ps1 new file mode 100644 index 0000000..da2f9f0 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#AuditPolicies.ps1 @@ -0,0 +1,2036 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "17.1.1" + Task = "(L1) Ensure 'Audit Credential Validation' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.1.2" + Task = "(L1) Ensure 'Audit Kerberos Authentication Service' is set to 'Success and Failure' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Kerberos Authentication Service + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kerberos Authentication Service" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kerberos Authentication Service'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.1.3" + Task = "(L1) Ensure 'Audit Kerberos Service Ticket Operations' is set to 'Success and Failure' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Kerberos Service Ticket Operations + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kerberos Service Ticket Operations" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kerberos Service Ticket Operations'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.1" + Task = "(L1) Ensure 'Audit Application Group Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Application Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Application Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Application Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.2" + Task = "(L1) Ensure 'Audit Computer Account Management' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Computer Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Computer Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Computer Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.3" + Task = "(L1) Ensure 'Audit Distribution Group Management' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Distribution Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Distribution Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Distribution Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.4" + Task = "(L1) Ensure 'Audit Other Account Management Events' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.5" + Task = "(L1) Ensure 'Audit Security Group Management' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.6" + Task = "(L1) Ensure 'Audit User Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.1" + Task = "(L1) Ensure 'Audit PNP Activity' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.2" + Task = "(L1) Ensure 'Audit Process Creation' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.4.1" + Task = "(L1) Ensure 'Audit Directory Service Access' is set to include 'Failure' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Directory Service Access + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Access" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Access'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.4.2" + Task = "(L1) Ensure 'Audit Directory Service Changes' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Directory Service Changes + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Changes" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Changes'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.1" + Task = "(L1) Ensure 'Audit Account Lockout' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.2" + Task = "(L1) Ensure 'Audit Group Membership' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.3" + Task = "(L1) Ensure 'Audit Logoff' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.4" + Task = "(L1) Ensure 'Audit Logon' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.5" + Task = "(L1) Ensure 'Audit Other Logon/Logoff Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.6" + Task = "(L1) Ensure 'Audit Special Logon' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.1" + Task = "(L1) Ensure 'Audit Detailed File Share' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.2" + Task = "(L1) Ensure 'Audit File Share' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.3" + Task = "(L1) Ensure 'Audit Other Object Access Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.4" + Task = "(L1) Ensure 'Audit Removable Storage' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.1" + Task = "(L1) Ensure 'Audit Audit Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.2" + Task = "(L1) Ensure 'Audit Authentication Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.3" + Task = "(L1) Ensure 'Audit Authorization Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.4" + Task = "(L1) Ensure 'Audit MPSSVC Rule-Level Policy Change' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Mpssvc Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Mpssvc Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Mpssvc Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.5" + Task = "(L1) Ensure 'Audit Other Policy Change Events' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.8.1" + Task = "(L1) Ensure 'Audit Sensitive Privilege Use' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.1" + Task = "(L1) Ensure 'Audit IPsec Driver' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Ipsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Ipsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Ipsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.2" + Task = "(L1) Ensure 'Audit Other System Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.3" + Task = "(L1) Ensure 'Audit Security State Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.4" + Task = "(L1) Ensure 'Audit Security System Extension' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.5" + Task = "(L1) Ensure 'Audit System Integrity' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#RegistrySettings.ps1 new file mode 100644 index 0000000..137a206 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#RegistrySettings.ps1 @@ -0,0 +1,13246 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "1.1.6" + Task = "(L1) Ensure 'Relax minimum password length limits' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SAM" ` + -Name "RelaxMinimumPasswordLengthLimits" ` + | Select-Object -ExpandProperty "RelaxMinimumPasswordLengthLimits" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.1" + Task = "(L1) Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "NoConnectedUser" ` + | Select-Object -ExpandProperty "NoConnectedUser" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.3" + Task = "(L1) Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.1" + Task = "(L1) Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.2" + Task = "(L1) Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "CrashOnAuditFail" ` + | Select-Object -ExpandProperty "CrashOnAuditFail" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4.1" + Task = "(L1) Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.1" + Task = "(L1) Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SubmitControl" ` + | Select-Object -ExpandProperty "SubmitControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.2" + Task = "(L1) Ensure 'Domain controller: Allow vulnerable Netlogon secure channel connections' is set to 'Not Configured' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "vulnerablechannelallowlist" ` + | Select-Object -ExpandProperty "vulnerablechannelallowlist" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.3" + Task = "(L1) Ensure 'Domain controller: LDAP server channel binding token requirements' is set to 'Always' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LdapEnforceChannelBinding" ` + | Select-Object -ExpandProperty "LdapEnforceChannelBinding" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.4" + Task = "(L1) Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LDAPServerIntegrity" ` + | Select-Object -ExpandProperty "LDAPServerIntegrity" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.5" + Task = "(L1) Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RefusePasswordChange" ` + | Select-Object -ExpandProperty "RefusePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.1" + Task = "(L1) Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.2" + Task = "(L1) Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.3" + Task = "(L1) Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.4" + Task = "(L1) Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.5" + Task = "(L1) Ensure 'Domain member: Maximum machine account password age' is set to '30 or fewer days, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if (($regValue -le 0 -or $regValue -gt 30)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x > 0 and x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.6" + Task = "(L1) Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.1" + Task = "(L1) Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.2" + Task = "(L1) Ensure 'Interactive logon: Don't display last signed-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.3" + Task = "(L1) Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.4" + Task = "(L1) Configure 'Interactive logon: Message text for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.5" + Task = "(L1) Configure 'Interactive logon: Message title for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.6" + Task = "(L2) Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "CachedLogonsCount" ` + | Select-Object -ExpandProperty "CachedLogonsCount" + + if ($regValue -notmatch "^[43210]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[43210]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.7" + Task = "(L1) Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if (($regValue -gt 14 -or $regValue -lt 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 14 and x >= 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.8" + Task = "(L1) Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ForceUnlockLogon" ` + | Select-Object -ExpandProperty "ForceUnlockLogon" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.9" + Task = "(L1) Ensure 'Interactive logon: Smart card removal behavior' is set to 1 - 'Lock Workstation' or 2 / 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -notmatch "^(1|2|3)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(1|2|3)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.8.1" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.2" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.3" + Task = "(L1) Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.1" + Task = "(L1) Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if (($regValue -gt 15)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.2" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.3" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'" + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.4" + Task = "(L1) Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "enableforcedlogoff" ` + | Select-Object -ExpandProperty "enableforcedlogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.5" + Task = "(L1) Ensure 'Microsoft network server: Server SPN target name validation level' is set to 1 - 'Accept if provided by client' or 2 - higher (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "SMBServerNameHardeningLevel" ` + | Select-Object -ExpandProperty "SMBServerNameHardeningLevel" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.2" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.3" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.4" + Task = "(L2) Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.5" + Task = "(L1) Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.6" + Task = "(L1) Configure 'Network access: Named Pipes that can be accessed anonymously' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + $reference = @( + "LSARPC" + "NETLOGON" + "SAMR" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: LSARPC NETLOGON SAMR" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.7" + Task = "(L1) Configure 'Network access: Named Pipes that can be accessed anonymously' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.8" + Task = "(L1) Configure 'Network access: Remotely accessible registry paths'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\ProductOptions" + "System\CurrentControlSet\Control\Server Applications" + "Software\Microsoft\Windows NT\CurrentVersion" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\ProductOptions System\CurrentControlSet\Control\Server Applications Software\Microsoft\Windows NT\CurrentVersion" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +$CARoleStatus = (Get-WindowsFeature -Name ADCS-Cert-Authority).Installed +$WINSStatus = (Get-WindowsFeature -Name WINS).Installed +[AuditTest] @{ + Id = "2.3.10.9 A" + Task = "(L1) Configure 'Network access: Remotely accessible registry paths and sub-paths' [WINS Role Feature and CA Role Service NOT installed]" + Test = { + try { + if (($CARoleStatus -or $WINSStatus) -eq $true){ + return @{ + Message = "WINS Role Feature or CA Role Service are installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9 B" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured [CA Role Service installed]" + Test = { + try { + if ($CARoleStatus -eq $false){ + return @{ + Message = "CA Role Service NOT installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + "System\CurrentControlSet\Services\CertSvc" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog System\CurrentControlSet\Services\CertSvc" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9 C" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured [WINS Role Feature installed]" + Test = { + try { + if ($WINSStatus -eq $false){ + return @{ + Message = "WINS Role Feature NOT installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + "System\CurrentControlSet\Services\WINS" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog System\CurrentControlSet\Services\WINS" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.10" + Task = "(L1) Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.11" + Task = "(L1) Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "restrictremotesam" ` + | Select-Object -ExpandProperty "restrictremotesam" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.12" + Task = "(L1) Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionShares" ` + | Select-Object -ExpandProperty "NullSessionShares" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.13" + Task = "(L1) Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.1" + Task = "(L1) Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.2" + Task = "(L1) Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.3" + Task = "(L1) Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.4" + Task = "(L1) Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.5" + Task = "(L1) Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.7" + Task = "(L1) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.8" + Task = "(L1) Ensure 'Network security: LDAP client signing requirements' is set to 1 - 'Negotiate signing' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.9" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.10" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.11" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Audit Incoming NTLM Traffic' is set to 'Enable auditing for all accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AuditReceivingNTLMTraffic" ` + | Select-Object -ExpandProperty "AuditReceivingNTLMTraffic" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.12" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Audit NTLM authentication in this domain' is set to 'Enable all' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "AuditNTLMInDomain" ` + | Select-Object -ExpandProperty "AuditNTLMInDomain" + + if ($regValue -ne 7) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 7" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.13" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers' is set to 1 - 'Audit all' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "RestrictSendingNTLMTraffic" ` + | Select-Object -ExpandProperty "RestrictSendingNTLMTraffic" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.13.1" + Task = "(L1) Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ShutdownWithoutLogon" ` + | Select-Object -ExpandProperty "ShutdownWithoutLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.1" + Task = "(L1) Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.2" + Task = "(L1) Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.1" + Task = "(L1) Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.2" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 2 - 'Prompt for consent on the secure desktop' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.3" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.4" + Task = "(L1) Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.5" + Task = "(L1) Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.6" + Task = "(L1) Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.7" + Task = "(L1) Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.8" + Task = "(L1) Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1" + Task = "(L1) Ensure 'Print Spooler (Spooler)' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2" + Task = "(L2) Ensure 'Print Spooler (Spooler)' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.1.1" + Task = "(L1) Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.2" + Task = "(L1) Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.3" + Task = "(L1) Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.4" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\domainfw.log'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\domainfw.log"; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.5" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.6" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.7" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.1" + Task = "(L1) Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.2" + Task = "(L1) Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.3" + Task = "(L1) Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.4" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\privatefw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\privatefw.log"; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.5" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.6" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.7" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.1" + Task = "(L1) Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.2" + Task = "(L1) Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.3" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.4" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.5" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.6" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\publicfw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\publicfw.log"; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.7" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.8" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.9" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "18.1.1.1" + Task = "(L1) Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.1.2" + Task = "(L1) Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.2.2" + Task = "(L1) Ensure 'Allow users to enable online speech recognition services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "AllowInputPersonalization" ` + | Select-Object -ExpandProperty "AllowInputPersonalization" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.3" + Task = "(L2) Ensure 'Allow Online Tips' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "AllowOnlineTips" ` + | Select-Object -ExpandProperty "AllowOnlineTips" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.1" + Task = "(L1) Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.2" + Task = "(L1) Ensure 'Configure RPC packet level privacy setting for incoming connections' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print" ` + -Name "RpcAuthnLevelPrivacyEnabled" ` + | Select-Object -ExpandProperty "RpcAuthnLevelPrivacyEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.3" + Task = "(L1) Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.4" + Task = "(L1) Ensure 'Configure SMB v1 server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.5" + Task = "(L1) Ensure 'Enable Certificate Padding' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Wintrust\Config" ` + -Name "EnableCertPaddingCheck" ` + | Select-Object -ExpandProperty "EnableCertPaddingCheck" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.6" + Task = "(L1) Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.7" + Task = "(L1) Ensure 'NetBT NodeType configuration' is set to 'Enabled: P-node (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.8" + Task = "(L1) Ensure 'WDigest Authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.1" + Task = "(L1) Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.2" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.3" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.4" + Task = "(L1) Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.5" + Task = "(L2) Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "KeepAliveTime" ` + | Select-Object -ExpandProperty "KeepAliveTime" + + if ($regValue -ne 300000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 300000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.6" + Task = "(L1) Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.7" + Task = "(L2) Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "PerformRouterDiscovery" ` + | Select-Object -ExpandProperty "PerformRouterDiscovery" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.8" + Task = "(L1) Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.9" + Task = "(L1) Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScreenSaverGracePeriod" ` + | Select-Object -ExpandProperty "ScreenSaverGracePeriod" + + if ($regValue -notmatch "^[0-5]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[0-5]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.10" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.11" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.12" + Task = "(L1) Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security" ` + -Name "WarningLevel" ` + | Select-Object -ExpandProperty "WarningLevel" + + if (($regValue -gt 90)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 90" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.1" + Task = "(L1) Ensure 'Configure DNS over HTTPS (DoH) name resolution' is set to 2 - 'Enabled: Allow DoH' or 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "DoHPolicy" ` + | Select-Object -ExpandProperty "DoHPolicy" + + if (($regValue -ne 2) -and ($regValue -ne 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2 or x == 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.2" + Task = "(L1) Ensure 'Configure NetBIOS settings' is set to 2 - 'Enabled: Disable NetBIOS name resolution on public networks' (or 0 - Disable NetBIOS name resolution)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableNetbios" ` + | Select-Object -ExpandProperty "EnableNetbios" + + if (($regValue -ne 2) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.3" + Task = "(L1) Ensure 'Turn off multicast name resolution' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.5.1" + Task = "(L2) Ensure 'Enable Font Providers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableFontProviders" ` + | Select-Object -ExpandProperty "EnableFontProviders" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.1" + Task = "(L1) Ensure 'Enable insecure guest logons' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 A" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnDomain" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 B" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnPublicNet" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 C" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (EnableLLTDIO)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableLLTDIO" ` + | Select-Object -ExpandProperty "EnableLLTDIO" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 D" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitLLTDIOOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitLLTDIOOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 A" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnDomain" ` + | Select-Object -ExpandProperty "AllowRspndrOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 B" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnPublicNet" ` + | Select-Object -ExpandProperty "AllowRspndrOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 C" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (EnableRspndr)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableRspndr" ` + | Select-Object -ExpandProperty "EnableRspndr" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 D" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitRspndrOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitRspndrOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.10.2" + Task = "(L2) Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Peernet" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.2" + Task = "(L1) Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.3" + Task = "(L1) Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.4" + Task = "(L1) Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_StdDomainUserSetLocation" ` + | Select-Object -ExpandProperty "NC_StdDomainUserSetLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 A" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares' (\\*\NETLOGON)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "RequirePrivacy=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 B" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares' (\\*\SYSVOL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "RequirePrivacy=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.19.2.1" + Task = "(L2) Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "DisabledComponents" ` + | Select-Object -ExpandProperty "DisabledComponents" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 A" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (EnableRegistrars)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "EnableRegistrars" ` + | Select-Object -ExpandProperty "EnableRegistrars" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 B" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableUPnPRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableUPnPRegistrar" ` + | Select-Object -ExpandProperty "DisableUPnPRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 C" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableInBand802DOT11Registrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableInBand802DOT11Registrar" ` + | Select-Object -ExpandProperty "DisableInBand802DOT11Registrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 D" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableFlashConfigRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableFlashConfigRegistrar" ` + | Select-Object -ExpandProperty "DisableFlashConfigRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 E" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableWPDRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableWPDRegistrar" ` + | Select-Object -ExpandProperty "DisableWPDRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.2" + Task = "(L2) Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WCN\UI" ` + -Name "DisableWcnUi" ` + | Select-Object -ExpandProperty "DisableWcnUi" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.1" + Task = "(L1) Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled: 3 = Prevent Wi-Fi when on Ethernet'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fMinimizeConnections" ` + | Select-Object -ExpandProperty "fMinimizeConnections" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.2" + Task = "(L2) Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.1" + Task = "(L1) Ensure 'Allow Print Spooler to accept client connections' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "RegisterSpoolerRemoteRpcEndPoint" ` + | Select-Object -ExpandProperty "RegisterSpoolerRemoteRpcEndPoint" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.2" + Task = "(L1) Ensure 'Configure Redirection Guard' is set to 'Enabled: Redirection Guard Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "RedirectionGuardPolicy" ` + | Select-Object -ExpandProperty "RedirectionGuardPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.3" + Task = "(L1) Ensure 'Configure RPC connection settings: Protocol to use for outgoing RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcUseNamedPipeProtocol" ` + | Select-Object -ExpandProperty "RpcUseNamedPipeProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.4" + Task = "(L1) Ensure 'Configure RPC connection settings: Use authentication for outgoing RPC connections' is set to 'Enabled: Default'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcAuthentication" ` + | Select-Object -ExpandProperty "RpcAuthentication" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.5" + Task = "(L1) Ensure 'Configure RPC listener settings: Protocols to allow for incoming RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcProtocols" ` + | Select-Object -ExpandProperty "RpcProtocols" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.6" + Task = "(L1) Ensure 'Configure RPC listener settings: Authentication protocol to use for incoming RPC connections:' is set to 'Enabled: 0 - Negotiate' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "ForceKerberosForRpc" ` + | Select-Object -ExpandProperty "ForceKerberosForRpc" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0 or x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.7" + Task = "(L1) Ensure 'Configure RPC over TCP port' is set to 'Enabled: 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcTcpPort" ` + | Select-Object -ExpandProperty "RpcTcpPort" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.8" + Task = "(L1) Ensure 'Limits print driver installation to Administrators' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "RestrictDriverInstallationToAdministrators" ` + | Select-Object -ExpandProperty "RestrictDriverInstallationToAdministrators" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.9" + Task = "(L1) Ensure 'Manage processing of Queue-specific files' is set to 'Enabled: Limit Queue-specific files to Color profiles'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "CopyFilesPolicy" ` + | Select-Object -ExpandProperty "CopyFilesPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.10" + Task = "(L1) Ensure 'Point and Print Restrictions: When installing drivers for a new connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "NoWarningNoElevationOnInstall" ` + | Select-Object -ExpandProperty "NoWarningNoElevationOnInstall" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.11" + Task = "(L1) Ensure 'Point and Print Restrictions: When updating drivers for an existing connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "UpdatePromptSettings" ` + | Select-Object -ExpandProperty "UpdatePromptSettings" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.1.1" + Task = "(L2) Ensure 'Turn off notifications network usage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.3.1" + Task = "(L1) Ensure 'Include command line in process creation events' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.1" + Task = "(L1) Ensure 'Encryption Oracle Remediation' is set to 'Enabled: Force Updated Clients'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.2" + Task = "(L1) Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.1" + Task = "(NG) Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.2" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Select Platform Security Level' is set to 1 - 'Secure Boot' or 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if (($regValue -ne 1) -and ($regValue -ne 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.3" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Virtualization Based Protection of Code Integrity' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.4" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Require UEFI Memory Attributes Table' is set to 'True (checked)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HVCIMATRequired" ` + | Select-Object -ExpandProperty "HVCIMATRequired" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.5" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Enabled with UEFI lock' (MS Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.6" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Disabled' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.7" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Secure Launch Configuration' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureSystemGuardLaunch" ` + | Select-Object -ExpandProperty "ConfigureSystemGuardLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.2" + Task = "(L1) Ensure 'Prevent device metadata retrieval from the Internet' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" ` + -Name "PreventDeviceMetadataFromNetwork" ` + | Select-Object -ExpandProperty "PreventDeviceMetadataFromNetwork" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.13.1" + Task = "(L1) Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.2" + Task = "(L1) Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.3" + Task = "(L1) Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.4" + Task = "(L1) Ensure 'Configure security policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.5" + Task = "(L1) Ensure 'Configure security policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.6" + Task = "(L1) Ensure 'Continue experiences on this device' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableCdp" ` + | Select-Object -ExpandProperty "EnableCdp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.7" + Task = "(L1) Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableBkGndGroupPolicy" ` + | Select-Object -ExpandProperty "DisableBkGndGroupPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.1" + Task = "(L1) Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.2" + Task = "(L2) Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\TabletPC" ` + -Name "PreventHandwritingDataSharing" ` + | Select-Object -ExpandProperty "PreventHandwritingDataSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.3" + Task = "(L2) Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\HandwritingErrorReports" ` + -Name "PreventHandwritingErrorReports" ` + | Select-Object -ExpandProperty "PreventHandwritingErrorReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.4" + Task = "(L2) Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Internet Connection Wizard" ` + -Name "ExitOnMSICW" ` + | Select-Object -ExpandProperty "ExitOnMSICW" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.5" + Task = "(L1) Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.6" + Task = "(L2) Ensure 'Turn off printing over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.7" + Task = "(L2) Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Registration Wizard Control" ` + -Name "NoRegistration" ` + | Select-Object -ExpandProperty "NoRegistration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.8" + Task = "(L2) Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SearchCompanion" ` + -Name "DisableContentFileUpdates" ` + | Select-Object -ExpandProperty "DisableContentFileUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.9" + Task = "(L2) Ensure 'Turn off the `"Order Prints`" picture task' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoOnlinePrintsWizard" ` + | Select-Object -ExpandProperty "NoOnlinePrintsWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.10" + Task = "(L2) Ensure 'Turn off the `"Publish to Web`" task for files and folders' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoPublishingWizard" ` + | Select-Object -ExpandProperty "NoPublishingWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.11" + Task = "(L2) Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Messenger\Client" ` + -Name "CEIP" ` + | Select-Object -ExpandProperty "CEIP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.12" + Task = "(L2) Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SQMClient\Windows" ` + -Name "CEIPEnable" ` + | Select-Object -ExpandProperty "CEIPEnable" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13 A" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (Disabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13 B" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (DoReport)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\PCHealth\ErrorReporting" ` + -Name "DoReport" ` + | Select-Object -ExpandProperty "DoReport" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 A" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitBehavior)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitBehavior" ` + | Select-Object -ExpandProperty "DevicePKInitBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 B" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitEnabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitEnabled" ` + | Select-Object -ExpandProperty "DevicePKInitEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.1" + Task = "(L1) Ensure 'Enumeration policy for external devices incompatible with Kernel DMA Protection' is set to 'Enabled: Block All'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.1" + Task = "(L1) Ensure 'Configure password backup directory' is set to 'Enabled: Active Directory' or 'Enabled: Azure Active Directory'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "BackupDirectory" ` + | Select-Object -ExpandProperty "BackupDirectory" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.2" + Task = "(L1) Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PwdExpirationProtectionEnabled" ` + | Select-Object -ExpandProperty "PwdExpirationProtectionEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.3" + Task = "(L1) Ensure 'Enable password encryption' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "ADPasswordEncryptionEnabled" ` + | Select-Object -ExpandProperty "ADPasswordEncryptionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.4" + Task = "(L1) Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordComplexity" ` + | Select-Object -ExpandProperty "PasswordComplexity" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.5" + Task = "(L1) Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordLength" ` + | Select-Object -ExpandProperty "PasswordLength" + + if ($regValue -lt 15) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.6" + Task = "(L1) Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordAgeDays" ` + | Select-Object -ExpandProperty "PasswordAgeDays" + + if (($regValue -gt 30 -or $regValue -lt 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30 and x >= 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.7" + Task = "(L1) Ensure 'Post-authentication actions: Grace period (hours)' is set to 'Enabled: 8 or fewer hours, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PostAuthenticationResetDelay" ` + | Select-Object -ExpandProperty "PostAuthenticationResetDelay" + + if (($regValue -gt 8 -or $regValue -le 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 8 and x > 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.8" + Task = "(L1) Ensure 'Post-authentication actions: Actions' is set to 3 - 'Enabled: Reset the password and logoff the managed account' or 5 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PostAuthenticationActions" ` + | Select-Object -ExpandProperty "PostAuthenticationActions" + + if (($regValue -ne 3) -and ($regValue -ne 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3 or 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.1" + Task = "(L1) Ensure 'Allow Custom SSPs and APs to be loaded into LSASS' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "AllowCustomSSPsAPs" ` + | Select-Object -ExpandProperty "AllowCustomSSPsAPs" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.2" + Task = "(NG) Ensure 'Configures LSASS to run as a protected process' is set to 'Enabled: Enabled with UEFI Lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RunAsPPL" ` + | Select-Object -ExpandProperty "RunAsPPL" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.1" + Task = "(L2) Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Control Panel\International" ` + -Name "BlockUserInputMethodsForSignIn" ` + | Select-Object -ExpandProperty "BlockUserInputMethodsForSignIn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.1" + Task = "(L1) Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockUserFromShowingAccountDetailsOnSignin" ` + | Select-Object -ExpandProperty "BlockUserFromShowingAccountDetailsOnSignin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.2" + Task = "(L1) Ensure 'Do not display network selection UI' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.3" + Task = "(L1) Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DontEnumerateConnectedUsers" ` + | Select-Object -ExpandProperty "DontEnumerateConnectedUsers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.4" + Task = "(L1) Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.5" + Task = "(L1) Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.6" + Task = "(L1) Ensure 'Turn off picture password sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "BlockDomainPicturePassword" ` + | Select-Object -ExpandProperty "BlockDomainPicturePassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.7" + Task = "(L1) Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.31.1" + Task = "(L2) Ensure 'Allow Clipboard synchronization across devices' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowCrossDeviceClipboard" ` + | Select-Object -ExpandProperty "AllowCrossDeviceClipboard" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.31.2" + Task = "(L2) Ensure 'Allow upload of User Activities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "UploadUserActivities" ` + | Select-Object -ExpandProperty "UploadUserActivities" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.1" + Task = "(L2) Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.2" + Task = "(L2) Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.3" + Task = "(L1) Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.4" + Task = "(L1) Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.1" + Task = "(L1) Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.2" + Task = "(L1) Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.36.1" + Task = "(L1) Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "EnableAuthEpResolution" ` + | Select-Object -ExpandProperty "EnableAuthEpResolution" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.36.2" + Task = "(L2) Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.39.1" + Task = "(L1) Ensure 'Configure validation of ROCA-vulnerable WHfB keys during authentication' is set to 1 - 'Enabled: Audit' or 2 - higher (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\SAM" ` + -Name "SamNGCKeyROCAValidation" ` + | Select-Object -ExpandProperty "SamNGCKeyROCAValidation" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1" + Task = "(L2) Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.11.1" + Task = "(L2) Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d}" ` + -Name "ScenarioExecutionEnabled" ` + | Select-Object -ExpandProperty "ScenarioExecutionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.49.1" + Task = "(L2) Ensure 'Turn off the advertising ID' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" ` + -Name "DisabledByGroupPolicy" ` + | Select-Object -ExpandProperty "DisabledByGroupPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.51.1.1" + Task = "(L1) Ensure 'Enable Windows NTP Client' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.51.1.2" + Task = "(L1) Ensure 'Enable Windows NTP Server' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.3.1" + Task = "(L2) Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager" ` + -Name "AllowSharedLocalAppData" ` + | Select-Object -ExpandProperty "AllowSharedLocalAppData" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.5.1" + Task = "(L1) Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.1" + Task = "(L1) Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.2" + Task = "(L1) Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.7.3" + Task = "(L1) Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.8.1.1" + Task = "(L1) Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.10.1" + Task = "(L2) Ensure 'Allow Use of Camera' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera" ` + -Name "AllowCamera" ` + | Select-Object -ExpandProperty "AllowCamera" + + if ($regValue -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam" ` + -Name "Value" ` + | Select-Object -ExpandProperty "Value" + + if ($regValue -match "Deny") { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Camera is not deactivated." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "18.10.12.1" + Task = "(L1) Ensure 'Turn off cloud consumer account state content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableConsumerAccountStateContent" ` + | Select-Object -ExpandProperty "DisableConsumerAccountStateContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.12.2" + Task = "(L2) Ensure 'Turn off cloud optimized content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableCloudOptimizedContent" ` + | Select-Object -ExpandProperty "DisableCloudOptimizedContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.12.3" + Task = "(L1) Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.13.1" + Task = "(L1) Ensure 'Require pin for pairing' is set to 'Enabled: First Time' OR 'Enabled: Always'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect" ` + -Name "RequirePinForPairing" ` + | Select-Object -ExpandProperty "RequirePinForPairing" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.1" + Task = "(L1) Ensure 'Do not display the password reveal button' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.2" + Task = "(L1) Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.1" + Task = "(L1) Ensure 'Allow Diagnostic Data' is set to '0 - Enabled: Diagnostic data off (not recommended)' or '1 - Enabled: Send required diagnostic data'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0 or x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.2" + Task = "(L2) Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableEnterpriseAuthProxy" ` + | Select-Object -ExpandProperty "DisableEnterpriseAuthProxy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.3" + Task = "(L1) Ensure 'Disable OneSettings Downloads' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableOneSettingsDownloads" ` + | Select-Object -ExpandProperty "DisableOneSettingsDownloads" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.4" + Task = "(L1) Ensure 'Do not show feedback notifications' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DoNotShowFeedbackNotifications" ` + | Select-Object -ExpandProperty "DoNotShowFeedbackNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.5" + Task = "(L1) Ensure 'Enable OneSettings Auditing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "EnableOneSettingsAuditing" ` + | Select-Object -ExpandProperty "EnableOneSettingsAuditing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.6" + Task = "(L1) Ensure 'Limit Diagnostic Log Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDiagnosticLogCollection" ` + | Select-Object -ExpandProperty "LimitDiagnosticLogCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.7" + Task = "(L1) Ensure 'Limit Dump Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDumpCollection" ` + | Select-Object -ExpandProperty "LimitDumpCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.8" + Task = "(L1) Ensure 'Toggle user control over Insider builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" ` + -Name "AllowBuildPreview" ` + | Select-Object -ExpandProperty "AllowBuildPreview" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.1" + Task = "(L1) Ensure 'Enable App Installer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableAppInstaller" ` + | Select-Object -ExpandProperty "EnableAppInstaller" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.2" + Task = "(L1) Ensure 'Enable App Installer Experimental Features' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableExperimentalFeatures" ` + | Select-Object -ExpandProperty "EnableExperimentalFeatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.3" + Task = "(L1) Ensure 'Enable App Installer Hash Override' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableHashOverride" ` + | Select-Object -ExpandProperty "EnableHashOverride" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.17.4" + Task = "(L1) Ensure 'Enable App Installer ms-appinstaller protocol' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableMSAppInstallerProtocol" ` + | Select-Object -ExpandProperty "EnableMSAppInstallerProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.1.1" + Task = "(L1) Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.1.2" + Task = "(L1) Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.2.1" + Task = "(L1) Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.2.2" + Task = "(L1) Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 196608)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.3.1" + Task = "(L1) Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.3.2" + Task = "(L1) Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.4.1" + Task = "(L1) Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.25.4.2" + Task = "(L1) Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.28.2" + Task = "(L1) Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.28.3" + Task = "(L1) Ensure 'Turn off heap termination on corruption' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.28.4" + Task = "(L1) Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.36.1" + Task = "(L2) Ensure 'Turn off location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.40.1" + Task = "(L2) Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging" ` + -Name "AllowMessageSync" ` + | Select-Object -ExpandProperty "AllowMessageSync" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.41.1" + Task = "(L1) Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount" ` + -Name "DisableUserAuth" ` + | Select-Object -ExpandProperty "DisableUserAuth" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.5.1" + Task = "(L1) Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.5.2" + Task = "(L2) Ensure 'Join Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.1" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 A" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office communication application from creating child processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 B" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating executable content'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 C" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block abuse of exploited vulnerable signed drivers'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 D" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block execution of potentially obfuscated scripts'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 E" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from injecting code into other processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 F" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Adobe Reader from creating child processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 G" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Win32 API calls from Office macro'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 H" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block credential stealing from the Windows local security authority subsystem (lsass.exe)'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 I" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block untrusted and unsigned processes that run from USB'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 J" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block executable content from email client and webmail'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 K" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block JavaScript or VBScript from launching downloaded executable content'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 L" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating child processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.1.2 M" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block persistence through WMI event subscription'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.6.3.1" + Task = "(L1) Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.7.1" + Task = "(L1) Ensure 'Enable file hash computation feature' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\MpEngine" ` + -Name "EnableFileHashComputation" ` + | Select-Object -ExpandProperty "EnableFileHashComputation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.1" + Task = "(L1) Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.2" + Task = "(L1) Ensure 'Turn off real-time protection' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.3" + Task = "(L1) Ensure 'Turn on behavior monitoring' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.10.4" + Task = "(L1) Ensure 'Turn on script scanning' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableScriptScanning" ` + | Select-Object -ExpandProperty "DisableScriptScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.12.1" + Task = "(L2) Ensure 'Configure Watson events' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" ` + -Name "DisableGenericReports" ` + | Select-Object -ExpandProperty "DisableGenericReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.13.1" + Task = "(L1) Ensure 'Scan packed executables' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisablePackedExeScanning" ` + | Select-Object -ExpandProperty "DisablePackedExeScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.13.2" + Task = "(L1) Ensure 'Scan removable drives' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.13.3" + Task = "(L1) Ensure 'Turn on e-mail scanning' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.16" + Task = "(L1) Ensure 'Configure detection for potentially unwanted applications' is set to 'Enabled: Block'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.17" + Task = "(L1) Ensure 'Turn off Microsoft Defender AntiVirus' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "DisableAntiSpyware" ` + | Select-Object -ExpandProperty "DisableAntiSpyware" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.50.1" + Task = "(L1) Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.55.1" + Task = "(L2) Ensure 'Turn off Push To Install service' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall" ` + -Name "DisablePushToInstall" ` + | Select-Object -ExpandProperty "DisablePushToInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.2.2" + Task = "(L1) Ensure 'Do not allow passwords to be saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.2.1" + Task = "(L2) Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fSingleSessionPerUser" ` + | Select-Object -ExpandProperty "fSingleSessionPerUser" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.1" + Task = "(L2) Ensure 'Allow UI Automation redirection' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "EnableUiaRedirection" ` + | Select-Object -ExpandProperty "EnableUiaRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.2" + Task = "(L2) Ensure 'Do not allow COM port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCcm" ` + | Select-Object -ExpandProperty "fDisableCcm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.3" + Task = "(L1) Ensure 'Do not allow drive redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.4" + Task = "(L2) Ensure 'Do not allow location redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLocationRedir" ` + | Select-Object -ExpandProperty "fDisableLocationRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.5" + Task = "(L2) Ensure 'Do not allow LPT port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLPT" ` + | Select-Object -ExpandProperty "fDisableLPT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.6" + Task = "(L2) Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisablePNPRedir" ` + | Select-Object -ExpandProperty "fDisablePNPRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.3.7" + Task = "(L2) Ensure 'Do not allow WebAuthn redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableWebAuthn" ` + | Select-Object -ExpandProperty "fDisableWebAuthn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.1" + Task = "(L1) Ensure 'Always prompt for password upon connection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.2" + Task = "(L1) Ensure 'Require secure RPC communication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.3" + Task = "(L1) Ensure 'Require use of specific security layer for remote (RDP) connections' is set to 'Enabled: SSL'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SecurityLayer" ` + | Select-Object -ExpandProperty "SecurityLayer" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.4" + Task = "(L1) Ensure 'Require user authentication for remote connections by using Network Level Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "UserAuthentication" ` + | Select-Object -ExpandProperty "UserAuthentication" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.9.5" + Task = "(L1) Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.10.1" + Task = "(L2) Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less, but not Never (0)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxIdleTime" ` + | Select-Object -ExpandProperty "MaxIdleTime" + + if (($regValue -gt 900000 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900000 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.10.2" + Task = "(L2) Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxDisconnectionTime" ` + | Select-Object -ExpandProperty "MaxDisconnectionTime" + + if ($regValue -ne 60000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 60000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.11.1" + Task = "(L1) Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.3.11.2" + Task = "(L1) Ensure 'Do not use temporary folders per session' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "PerSessionTempDir" ` + | Select-Object -ExpandProperty "PerSessionTempDir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.1" + Task = "(L1) Ensure 'Prevent downloading of enclosures' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.2" + Task = "(L2) Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCloudSearch" ` + | Select-Object -ExpandProperty "AllowCloudSearch" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.3" + Task = "(L1) Ensure 'Allow indexing of encrypted files' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.4" + Task = "(L2) Ensure 'Allow search highlights' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "EnableDynamicContentInWSB" ` + | Select-Object -ExpandProperty "EnableDynamicContentInWSB" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.62.1" + Task = "(L2) Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" ` + -Name "NoGenTicket" ` + | Select-Object -ExpandProperty "NoGenTicket" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.75.2.1 A" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (EnableSmartScreen)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.75.2.1 B" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (ShellSmartScreenLevel)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.79.1" + Task = "(L2) Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowSuggestedAppsInWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowSuggestedAppsInWindowsInkWorkspace" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.79.2" + Task = "(L1) Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Enabled: Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if (($regValue -ne 1) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.1" + Task = "(L1) Ensure 'Allow user control over installs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.2" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.3" + Task = "(L2) Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.1" + Task = "(L1) Ensure 'Enable MPR notifications for the system' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableMPR" ` + | Select-Object -ExpandProperty "EnableMPR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.2" + Task = "(L1) Ensure 'Sign-in and lock last interactive user automatically after a restart' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.86.1" + Task = "(L2) Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.86.2" + Task = "(L2) Ensure 'Turn on PowerShell Transcription' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" ` + -Name "EnableTranscripting" ` + | Select-Object -ExpandProperty "EnableTranscripting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.1.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.1.2" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.1.3" + Task = "(L1) Ensure 'Disallow Digest authentication' is set to 'Enabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.2" + Task = "(L2) Ensure 'Allow remote server management through WinRM' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowAutoConfig" ` + | Select-Object -ExpandProperty "AllowAutoConfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.3" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.88.2.4" + Task = "(L1) Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1" + Task = "(L2) Ensure 'Allow Remote Shell Access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service\WinRS" ` + -Name "AllowRemoteShellAccess" ` + | Select-Object -ExpandProperty "AllowRemoteShellAccess" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.91.2.1" + Task = "(L1) Ensure 'Prevent users from modifying settings' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection" ` + -Name "DisallowExploitProtectionOverride" ` + | Select-Object -ExpandProperty "DisallowExploitProtectionOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.1.1" + Task = "(L1) Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.1" + Task = "(L1) Ensure 'Configure Automatic Updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.2" + Task = "(L1) Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.1" + Task = "(L1) Ensure 'Manage preview builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "ManagePreviewBuildsPolicyValue" ` + | Select-Object -ExpandProperty "ManagePreviewBuildsPolicyValue" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.2 A" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdates" ` + | Select-Object -ExpandProperty "DeferFeatureUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.2 B" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferFeatureUpdatesPeriodInDays" + + if (($regValue -lt 180 -or $regValue -gt 365)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 180 and x <= 365" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.3 A" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdates" ` + | Select-Object -ExpandProperty "DeferQualityUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.4.3 B" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferQualityUpdatesPeriodInDays" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.5.1.1" + Task = "(L1) Ensure 'Turn off toast notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.6.6.1.1" + Task = "(L2) Ensure 'Turn off Help Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Assistance\Client\1.0" ` + -Name "NoImplicitFeedback" ` + | Select-Object -ExpandProperty "NoImplicitFeedback" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.5.1" + Task = "(L1) Ensure 'Do not preserve zone information in file attachments' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.5.2" + Task = "(L1) Ensure 'Notify antivirus programs when opening attachments' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "ScanWithAntiVirus" ` + | Select-Object -ExpandProperty "ScanWithAntiVirus" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.1" + Task = "(L1) Ensure 'Configure Windows spotlight on lock screen' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "ConfigureWindowsSpotlight" ` + | Select-Object -ExpandProperty "ConfigureWindowsSpotlight" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.2" + Task = "(L1) Ensure 'Do not suggest third-party content in Windows spotlight' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.3" + Task = "(L2) Ensure 'Do not use diagnostic data for tailored experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableTailoredExperiencesWithDiagnosticData" ` + | Select-Object -ExpandProperty "DisableTailoredExperiencesWithDiagnosticData" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.4" + Task = "(L2) Ensure 'Turn off all Windows spotlight features' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsSpotlightFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsSpotlightFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.5" + Task = "(L1) Ensure 'Turn off Spotlight collection on Desktop' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableSpotlightCollectionOnDesktop" ` + | Select-Object -ExpandProperty "DisableSpotlightCollectionOnDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.26.1" + Task = "(L1) Ensure 'Prevent users from sharing files within their profile.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInplaceSharing" ` + | Select-Object -ExpandProperty "NoInplaceSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.42.1" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled' (AlwaysInstallElevated)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.44.2.1" + Task = "(L2) Ensure 'Prevent Codec Download' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\WindowsMediaPlayer" ` + -Name "PreventCodecDownload" ` + | Select-Object -ExpandProperty "PreventCodecDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#SecurityOptions.ps1 new file mode 100644 index 0000000..59b8d27 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#SecurityOptions.ps1 @@ -0,0 +1,133 @@ +[AuditTest] @{ + Id = "2.3.1.2" + Task = "(L1) Ensure 'Accounts: Guest account status' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.4" + Task = "(L1) Configure 'Accounts: Rename administrator account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption. Expected: ^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.5" + Task = "(L1) Configure 'Accounts: Rename guest account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption. Expected: ^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.1" + Task = "(L1) Ensure 'Network access: Allow anonymous SID/Name translation' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.6" + Task = "(L1) Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["ForceLogoffWhenHourExpire"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 1) { + return @{ + Message = "'ForceLogoffWhenHourExpire' currently set to: $setOption. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#UserRights.ps1 new file mode 100644 index 0000000..19b8054 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-CIS-3.0.0#UserRights.ps1 @@ -0,0 +1,1985 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + if ($sidAccount.Translate([System.Security.Principal.NTAccount]) -eq "NULL SID") { + return @{ + Account = $null + Sid = $sidAccount.Value + } + } else { + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "2.2.1" + Task = "(L1) Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Authenticated Users, ENTERPRISE DOMAIN CONTROLLERS' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-11" + "S-1-5-32-544" + "S-1-5-9" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.3" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Authenticated Users' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-11" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.4" + Task = "(L1) Ensure 'Act as part of the operating system' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.5" + Task = "(L1) Ensure 'Add workstations to domain' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeMachineAccountPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeMachineAccountPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeMachineAccountPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.6" + Task = "(L1) Ensure 'Adjust memory quotas for a process' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseQuotaPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseQuotaPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseQuotaPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.7" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators, ENTERPRISE DOMAIN CONTROLLERS' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-9" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.8" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.9" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.10" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators, Remote Desktop Users' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.11" + Task = "(L1) Ensure 'Back up files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.12" + Task = "(L1) Ensure 'Change the system time' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemtimePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemtimePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemtimePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.13" + Task = "(L1) Ensure 'Change the time zone' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTimeZonePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTimeZonePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTimeZonePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Ensure 'Create a pagefile' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.15" + Task = "(L1) Ensure 'Create a token object' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.16" + Task = "(L1) Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.17" + Task = "(L1) Ensure 'Create permanent shared objects' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.18" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if($hyperVStatus -ne "Enabled"){ +[AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators [Hyper-V-Feature NOT installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +} +else{ +[AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators, NT VIRTUAL MACHINE\Virtual Machines' [Hyper-V-Feature installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.20" + Task = "(L1) Ensure 'Debug programs' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.21" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.22" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests, Local account and member of Administrators group' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + "S-1-5-114" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.23" + Task = "(L1) Ensure 'Deny log on as a batch job' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.24" + Task = "(L1) Ensure 'Deny log on as a service' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyServiceLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.25" + Task = "(L1) Ensure 'Deny log on locally' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.26" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' to include 'Guests' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.27" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' is set to 'Guests, Local account' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.28" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.29" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'No One' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.30" + Task = "(L1) Ensure 'Force shutdown from a remote system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +$adfsModule = Get-Module -Name ADFS +if($null -eq $adfsModule){ +[AuditTest] @{ + Id = "2.2.31 A" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE' [ADFS-ROLE NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +} +else{ +[AuditTest] @{ + Id = "2.2.31 B" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE' [ADFS-ROLE installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-80-1321940109-3370001082-3650459431-215109509-2472514016" + "S-1-5-80-2246541699-21809830-3603976364-117610243-975697593" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.32" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if((Get-WindowsFeature -Name web-server).installed -ne $true){ +[AuditTest] @{ + Id = "2.2.33 A" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE' [IIS Role NOT installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +} +else{ +[AuditTest] @{ + Id = "2.2.33 B" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE, IIS_IUSRS' [IIS Role installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-32-568" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.34" + Task = "(L1) Ensure 'Increase scheduling priority' is set to 'Administrators, Window Manager\Window Manager Group'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseBasePriorityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-90-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseBasePriorityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseBasePriorityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.35" + Task = "(L1) Ensure 'Load and unload device drivers' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.36" + Task = "(L1) Ensure 'Lock pages in memory' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.37" + Task = "(L2) Ensure 'Log on as a batch job' is set to 'Administrators' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBatchLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.38" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators' and (when Exchange is running in the environment) 'Exchange Servers' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.39" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.40" + Task = "(L1) Ensure 'Modify an object label' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRelabelPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRelabelPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRelabelPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.41" + Task = "(L1) Ensure 'Modify firmware environment values' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.42" + Task = "(L1) Ensure 'Perform volume maintenance tasks' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.43" + Task = "(L1) Ensure 'Profile single process' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.44" + Task = "(L1) Ensure 'Profile system performance' is set to 'Administrators, NT SERVICE\WdiServiceHost'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemProfilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemProfilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemProfilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.45" + Task = "(L1) Ensure 'Replace a process level token' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAssignPrimaryTokenPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAssignPrimaryTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAssignPrimaryTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.46" + Task = "(L1) Ensure 'Restore files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.47" + Task = "(L1) Ensure 'Shut down the system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.48" + Task = "(L1) Ensure 'Synchronize directory service data' is set to 'No One' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSyncAgentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSyncAgentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSyncAgentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.49" + Task = "(L1) Ensure 'Take ownership of files or other objects' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#AccountPolicies.ps1 new file mode 100644 index 0000000..e75e12b --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#AccountPolicies.ps1 @@ -0,0 +1,252 @@ +[AuditTest] @{ + Id = "V-254285" + Task = "Windows Server 2022 account lockout duration must be configured to 15 or greater." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15) -and ($setPolicy -ne 0 )) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15 or x == 0 " + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254286" + Task = "Windows Server 2022 must have the number of allowed bad logon attempts configured to three or less." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 3 -or $setPolicy -eq 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x >= 3 and x != 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254287" + Task = "Windows Server 2022 must have the period of time before the bad logon counter is reset configured to 15 or greater." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 15 )) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x >= 15 " + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254288" + Task = "Windows Server 2022 password history must be configured to 24 passwords remembered." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254289" + Task = "Windows Server 2022 maximum password age must be configured to 60 or less." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 60 -or $setPolicy -eq 0 )) { + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 60 and x != 0 " + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254290" + Task = "Windows Server 2022 minimum password age must be configured to at least one day." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -eq 0 )) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x != 0 " + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254291" + Task = "Windows Server 2020 minimum password length must be configured to 14 characters." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254292" + Task = "Windows Server 2022 must have the built-in Windows password complexity policy enabled." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254293" + Task = "Windows Server 2022 reversible password encryption must be disabled." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#AuditPolicies.ps1 new file mode 100644 index 0000000..03362a9 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#AuditPolicies.ps1 @@ -0,0 +1,1502 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "V-254300 + V-254301" + Task = "Windows Server 2022 must be configured to audit Account Logon - Credential Validation successes. Windows Server 2022 must be configured to audit Account Logon - Credential Validation failures." + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254302" + Task = "Windows Server 2022 must be configured to audit Account Management - Other Account Management Events successes." + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254303" + Task = "Windows Server 2022 must be configured to audit Account Management - Security Group Management successes." + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254304 + V-254305" + Task = "Windows Server 2022 must be configured to audit Account Management - User Account Management successes. Windows Server 2022 must be configured to audit Account Management - User Account Management failures." + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254306" + Task = "Windows Server 2022 must be configured to audit Detailed Tracking - Plug and Play Events successes." + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254307" + Task = "Windows Server 2022 must be configured to audit Detailed Tracking - Process Creation successes." + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254308 + V-254309" + Task = "Windows Server 2022 must be configured to audit Logon/Logoff - Account Lockout successes. Windows Server 2022 must be configured to audit Logon/Logoff - Account Lockout failures." + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254310" + Task = "Windows Server 2022 must be configured to audit Logon/Logoff - Group Membership successes." + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254311" + Task = "Windows Server 2022 must be configured to audit logoff successes." + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254312 + V-254313" + Task = "Windows Server 2022 must be configured to audit logon successes. Windows Server 2022 must be configured to audit logon failures." + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254314" + Task = "Windows Server 2022 must be configured to audit Logon/Logoff - Special Logon successes." + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254315 + V-254316" + Task = "Windows Server 2022 must be configured to audit Object Access - Other Object Access Events successes. Windows Server 2022 must be configured to audit Object Access - Other Object Access Events failures." + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254317 + V-254318" + Task = "Windows Server 2022 must be configured to audit Object Access - Removable Storage successes. Windows Server 2022 must be configured to audit Object Access - Removable Storage failures." + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254319 + V-254320" + Task = "Windows Server 2022 must be configured to audit Policy Change - Audit Policy Change successes. Windows Server 2022 must be configured to audit Policy Change - Audit Policy Change failures." + Test = { + # Get the audit policy for the subcategory Audit Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254321" + Task = "Windows Server 2022 must be configured to audit Policy Change - Authentication Policy Change successes." + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254322" + Task = "Windows Server 2022 must be configured to audit Policy Change - Authorization Policy Change successes." + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254323 + V-254324" + Task = "Windows Server 2022 must be configured to audit Privilege Use - Sensitive Privilege Use successes. Windows Server 2022 must be configured to audit Privilege Use - Sensitive Privilege Use failures." + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254325 + V-254326" + Task = "Windows Server 2022 must be configured to audit System - IPsec Driver successes. Windows Server 2022 must be configured to audit System - IPsec Driver failures." + Test = { + # Get the audit policy for the subcategory IPsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "IPsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'IPsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254327 + V-254328" + Task = "Windows Server 2022 must be configured to audit System - Other System Events successes. Windows Server 2022 must be configured to audit System - Other System Events failures." + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254329" + Task = "Windows Server 2022 must be configured to audit System - Security State Change successes." + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254330" + Task = "Windows Server 2022 must be configured to audit System - Security System Extension successes." + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254331 + V-254332" + Task = "Windows Server 2022 must be configured to audit System - System Integrity successes. Windows Server 2022 must be configured to audit System - System Integrity failures." + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254407" + Task = "Windows Server 2022 must be configured to audit Account Management - Computer Account Management successes." + Test = { + # Get the audit policy for the subcategory Computer Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Computer Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Computer Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254408 + V-254409" + Task = "Windows Server 2022 must be configured to audit DS Access - Directory Service Access successes. Windows Server 2022 must be configured to audit DS Access - Directory Service Access failures." + Test = { + # Get the audit policy for the subcategory Directory Service Access + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Access" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Access'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "V-254410 + V-254411" + Task = "Windows Server 2022 must be configured to audit DS Access - Directory Service Changes successes. Windows Server 2022 must be configured to audit DS Access - Directory Service Changes failures." + Test = { + # Get the audit policy for the subcategory Directory Service Changes + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Changes" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Changes'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#RegistrySettings.ps1 new file mode 100644 index 0000000..acf9f50 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#RegistrySettings.ps1 @@ -0,0 +1,3509 @@ +[AuditTest] @{ + Id = "V-254276" + Task = "Windows Server 2022 must have the Server Message Block (SMB) v1 protocol disabled on the SMB server." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254277" + Task = "Windows Server 2022 must have the Server Message Block (SMB) v1 protocol disabled on the SMB client." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254333" + Task = "Windows Server 2022 must prevent the display of slide shows on the lock screen." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254334" + Task = "Windows Server 2022 must have WDigest Authentication disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Wdigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254335" + Task = "Windows Server 2022 Internet Protocol version 6 (IPv6) source routing must be configured to the highest protection level to prevent IP source routing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254336" + Task = "Windows Server 2022 source routing must be configured to the highest protection level to prevent Internet Protocol (IP) source routing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254337" + Task = "Windows Server 2022 must be configured to prevent Internet Control Message Protocol (ICMP) redirects from overriding Open Shortest Path First (OSPF)-generated routes." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254338" + Task = "Windows Server 2022 must be configured to ignore NetBIOS name release requests except from WINS servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NoNameReleaseOnDemand" ` + | Select-Object -ExpandProperty "NoNameReleaseOnDemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254339" + Task = "Windows Server 2022 insecure logons to an SMB server must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254341" + Task = "Windows Server 2022 command line data must be included in process creation events." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254342" + Task = "Windows Server 2022 must be configured to enable Remote host allows delegation of nonexportable credentials." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254344" + Task = "Windows Server 2022 Early Launch Antimalware, Boot-Start Driver Initialization Policy must prevent boot drivers identified as bad." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if (($regValue -ne 1) -and ($regValue -ne 3) -and ($regValue -ne 8)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1 or x == 3 or x == 8" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254345" + Task = "Windows Server 2022 group policy objects must be reprocessed even if they have not changed." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254346" + Task = "Windows Server 2022 downloading print driver packages over HTTP must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254347" + Task = "Windows Server 2022 printing over HTTP must be turned off." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254348" + Task = "Windows Server 2022 network selection user interface (UI) must not be displayed on the logon screen." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254349" + Task = "Windows Server 2022 users must be prompted to authenticate when the system wakes from sleep (on battery)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254350" + Task = "Windows Server 2022 users must be prompted to authenticate when the system wakes from sleep (plugged in)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254351" + Task = "Windows Server 2022 Application Compatibility Program Inventory must be prevented from collecting data and sending the information to Microsoft." + Test = { + try { + $status = get-service -name pcasvc -ErrorAction Stop + if($status.Status -ne "Stopped"){ + return @{ + Message = "Compliant - AppCompat Service is disabled (no inventory data will be collected)." + Status = "True" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppCompat" ` + -Name "DisableInventory" ` + | Select-Object -ExpandProperty "DisableInventory" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + catch [System.SystemException]{ + return @{ + Message = "Service not found!" + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254352" + Task = "Windows Server 2022 Autoplay must be turned off for nonvolume devices." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254353" + Task = "Windows Server 2022 default AutoRun behavior must be configured to prevent AutoRun commands." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254354" + Task = "Windows Server 2022 AutoPlay must be disabled for all drives." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254355" + Task = "Windows Server 2022 administrator accounts must not be enumerated during elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254358" + Task = "Windows Server 2022 Application event log size must be configured to 32768 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254359" + Task = "Windows Server 2022 Security event log size must be configured to 196608 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 196608)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254360" + Task = "Windows Server 2022 System event log size must be configured to 32768 KB or greater." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254361" + Task = "Windows Server 2022 Microsoft Defender antivirus SmartScreen must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254362" + Task = "Windows Server 2022 Explorer Data Execution Prevention must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254363" + Task = "Windows Server 2022 Turning off File Explorer heap termination on corruption must be disabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254364" + Task = "Windows Server 2022 File Explorer shell protocol must run in protected mode." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254365" + Task = "Windows Server 2022 must not save passwords in the Remote Desktop Client." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254366" + Task = "Windows Server 2022 Remote Desktop Services must prevent drive redirection." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254367" + Task = "Windows Server 2022 Remote Desktop Services must always prompt a client for passwords upon connection." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254368" + Task = "Windows Server 2022 Remote Desktop Services must require secure Remote Procedure Call (RPC) communications." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254369" + Task = "Windows Server 2022 Remote Desktop Services must be configured with the client connection encryption set to High Level." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254370" + Task = "Windows Server 2022 must prevent attachments from being downloaded from RSS feeds." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254371" + Task = "Windows Server 2022 must disable Basic authentication for RSS feeds over HTTP." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "AllowBasicAuthInClear" ` + | Select-Object -ExpandProperty "AllowBasicAuthInClear" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254372" + Task = "Windows Server 2022 must prevent Indexing of encrypted files." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254373" + Task = "Windows Server 2022 must prevent users from changing installation options." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254374" + Task = "Windows Server 2022 must disable the Windows Installer Always install with elevated privileges option." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254375" + Task = "Windows Server 2022 users must be notified if a web-based program attempts to install software." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254376" + Task = "Windows Server 2022 must disable automatically signing in the last interactive user after a system-initiated restart." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254377" + Task = "Windows Server 2022 PowerShell script block logging must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254378" + Task = "Windows Server 2022 Windows Remote Management (WinRM) client must not use Basic authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254379" + Task = "Windows Server 2022 Windows Remote Management (WinRM) client must not allow unencrypted traffic." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254380" + Task = "Windows Server 2022 Windows Remote Management (WinRM) client must not use Digest authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254381" + Task = "Windows Server 2022 Windows Remote Management (WinRM) service must not use Basic authentication." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254382" + Task = "Windows Server 2022 Windows Remote Management (WinRM) service must not allow unencrypted traffic." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254383" + Task = "Windows Server 2022 Windows Remote Management (WinRM) service must not store RunAs credentials." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254384" + Task = "Windows Server 2022 must have PowerShell Transcription enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" ` + -Name "EnableTranscripting" ` + | Select-Object -ExpandProperty "EnableTranscripting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254416" + Task = "Windows Server 2022 domain controllers must require LDAP access signing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LDAPServerIntegrity" ` + | Select-Object -ExpandProperty "LDAPServerIntegrity" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254417" + Task = "Windows Server 2022 domain controllers must be configured to allow reset of machine account passwords." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RefusePasswordChange" ` + | Select-Object -ExpandProperty "RefusePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254429" + Task = "Windows Server 2022 local administrator accounts must have their privileged token filtered to prevent elevated privileges from being used over the network on domain-joined member servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254430" + Task = "Windows Server 2022 local users on domain-joined member servers must not be enumerated." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254431" + Task = "Windows Server 2022 must restrict unauthenticated Remote Procedure Call (RPC) clients from connecting to the RPC server on domain-joined member servers and standalone or nondomain-joined systems." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254433" + Task = "Windows Server 2022 must restrict remote calls to the Security Account Manager (SAM) to Administrators on domain-joined member servers and standalone or nondomain-joined systems." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictRemoteSAM" ` + | Select-Object -ExpandProperty "RestrictRemoteSAM" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254446" + Task = "Windows Server 2022 must prevent local accounts with blank passwords from being used from the network." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254449" + Task = "Windows Server 2022 must force audit policy subcategory settings to override audit policy category settings." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254450" + Task = "Windows Server 2022 setting Domain member: Digitally encrypt or sign secure channel data (always) must be configured to Enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254451" + Task = "Windows Server 2022 setting Domain member: Digitally encrypt secure channel data (when possible) must be configured to Enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254452" + Task = "Windows Server 2022 setting Domain member: Digitally sign secure channel data (when possible) must be configured to Enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254453" + Task = "Windows Server 2022 computer account password must not be prevented from being reset." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254454" + Task = "Windows Server 2022 maximum age for machine account passwords must be configured to 30 days or less." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if (($regValue -gt 30 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254455" + Task = "Windows Server 2022 must be configured to require a strong session key." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254456" + Task = "Windows Server 2022 machine inactivity limit must be set to 15 minutes or less, locking the system with the screen saver." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254457" + Task = "Windows Server 2022 required legal notice must be configured to display before console logon." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + if ($regValue -ne "See message text below") { + return @{ + Message = "Registry value is '$regValue'. Expected: See message text below" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254458" + Task = "Windows Server 2022 title for legal banner dialog box must be configured with the appropriate text." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + if ($regValue -ne "See message title options below") { + return @{ + Message = "Registry value is '$regValue'. Expected: See message title options below" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254460" + Task = "Windows Server 2022 setting Microsoft network client: Digitally sign communications (always) must be configured to Enabled." + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-254461" + Task = "Windows Server 2022 setting Microsoft network client: Digitally sign communications (if server agrees) must be configured to Enabled." + Test = { + try { + if((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-254462" + Task = "Windows Server 2022 unencrypted passwords must not be sent to third-party Server Message Block (SMB) servers." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254463" + Task = "Windows Server 2022 setting Microsoft network server: Digitally sign communications (always) must be configured to Enabled." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-254464" + Task = "Windows Server 2022 setting Microsoft network server: Digitally sign communications (if client agrees) must be configured to Enabled." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True){ + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "V-254466" + Task = "Windows Server 2022 must not allow anonymous enumeration of Security Account Manager (SAM) accounts." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254467" + Task = "Windows Server 2022 must not allow anonymous enumeration of shares." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254468" + Task = "Windows Server 2022 must be configured to prevent anonymous users from having the same permissions as the Everyone group." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254469" + Task = "Windows Server 2022 must restrict anonymous access to Named Pipes and Shares." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254470" + Task = "Windows Server 2022 services using Local System that use Negotiate when reverting to NTLM authentication must use the computer identity instead of authenticating anonymously." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254471" + Task = "Windows Server 2022 must prevent NTLM from falling back to a Null session." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA\MSV1_0" ` + -Name "allownullsessionfallback" ` + | Select-Object -ExpandProperty "allownullsessionfallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254472" + Task = "Windows Server 2022 must prevent PKU2U authentication using online identities." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254473" + Task = "Windows Server 2022 Kerberos encryption types must be configured to prevent the use of DES and RC4 encryption suites." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254474" + Task = "Windows Server 2022 must be configured to prevent the storage of the LAN Manager hash of passwords." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254475" + Task = "Windows Server 2022 LAN Manager authentication level must be configured to send NTLMv2 response only and to refuse LM and NTLM." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254476" + Task = "Windows Server 2022 must be configured to at least negotiate signing for LDAP client signing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254477" + Task = "Windows Server 2022 session security for NTLM SSP-based clients must be configured to require NTLMv2 session security and 128-bit encryption." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254478" + Task = "Windows Server 2022 session security for NTLM SSP-based servers must be configured to require NTLMv2 session security and 128-bit encryption." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254479" + Task = "Windows Server 2022 users must be required to enter a password to access private keys stored on the computer." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography" ` + -Name "ForceKeyProtection" ` + | Select-Object -ExpandProperty "ForceKeyProtection" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254480" + Task = "Windows Server 2022 must be configured to use FIPS-compliant algorithms for encryption, hashing, and signing." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254481" + Task = "Windows Server 2022 default permissions of global system objects must be strengthened." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254482" + Task = "Windows Server 2022 User Account Control (UAC) approval mode for the built-in Administrator must be enabled." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254483" + Task = "Windows Server 2022 UIAccess applications must not be allowed to prompt for elevation without using the secure desktop." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableUIADesktopToggle" ` + | Select-Object -ExpandProperty "EnableUIADesktopToggle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254485" + Task = "Windows Server 2022 User Account Control (UAC) must automatically deny standard user requests for elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254486" + Task = "Windows Server 2022 User Account Control (UAC) must be configured to detect application installations and prompt for elevation." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254487" + Task = "Windows Server 2022 User Account Control (UAC) must only elevate UIAccess applications that are installed in secure locations." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254488" + Task = "Windows Server 2022 User Account Control (UAC) must run all administrators in Admin Approval Mode, enabling UAC." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254489" + Task = "Windows Server 2022 User Account Control (UAC) must virtualize file and registry write failures to per-user locations." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254490" + Task = "Windows Server 2022 must preserve zone information when saving attachments." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#SecurityOptions.ps1 new file mode 100644 index 0000000..28caf72 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-DISA-V1R1#SecurityOptions.ps1 @@ -0,0 +1,104 @@ +[AuditTest] @{ + Id = "V-254445" + Task = "Windows Server 2022 must have the built-in guest account disabled." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254447" + Task = "Windows Server 2022 built-in administrator account must be renamed." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?!.*\bAdministrator\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254448" + Task = "Windows Server 2022 built-in guest account must be renamed." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "V-254465" + Task = "Windows Server 2022 must not allow anonymous SID/Name translation." + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#AccountPolicies.ps1 new file mode 100644 index 0000000..e0b4a36 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#AccountPolicies.ps1 @@ -0,0 +1,196 @@ +[AuditTest] @{ + Id = "AccountPolicy-309" + Task = "Ensure 'MinimumPasswordLength' is set to '14'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -ne 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x == 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-310" + Task = "Ensure 'PasswordComplexity' is set to '1'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-311" + Task = "Ensure 'PasswordHistorySize' is set to '24'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -ne 24)) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: x == 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-312" + Task = "Ensure 'LockoutBadCount' is set to '10'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -ne 10)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x == 10" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-313" + Task = "Ensure 'ResetLockoutCount' is set to '15'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -ne 15)) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x == 15 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-314" + Task = "Ensure 'LockoutDuration' is set to '15'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -ne 15)) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x == 15 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "AccountPolicy-315" + Task = "Ensure 'ClearTextPassword' is set to '0'." + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#AuditPolicies.ps1 new file mode 100644 index 0000000..85187c7 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#AuditPolicies.ps1 @@ -0,0 +1,1730 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "AuditPolicy-250" + Task = "Ensure 'Credential Validation' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-251" + Task = "Ensure 'Security Group Management' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-252" + Task = "Ensure 'User Account Management' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-253" + Task = "Ensure 'Plug and Play Events' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-254" + Task = "Ensure 'Process Creation' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-255" + Task = "Ensure 'Account Lockout' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-256" + Task = "Ensure 'Group Membership' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-257" + Task = "Ensure 'Logon' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-258" + Task = "Ensure 'Other Logon/Logoff Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-259" + Task = "Ensure 'Special Logon' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-260" + Task = "Ensure 'Detailed File Share' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-261" + Task = "Ensure 'File Share' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-262" + Task = "Ensure 'Other Object Access Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-263" + Task = "Ensure 'Removable Storage' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-264" + Task = "Ensure 'Audit Policy Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-265" + Task = "Ensure 'Authentication Policy Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-266" + Task = "Ensure 'MPSSVC Rule-Level Policy Change' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory MPSSVC Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "MPSSVC Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'MPSSVC Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-267" + Task = "Ensure 'Other Policy Change Events' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-268" + Task = "Ensure 'Sensitive Privilege Use' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-269" + Task = "Ensure 'Other System Events' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-270" + Task = "Ensure 'Security State Change' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-271" + Task = "Ensure 'Security System Extension' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-272" + Task = "Ensure 'System Integrity' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-449" + Task = "Ensure 'Kerberos Authentication Service' is set to 'Success' and is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Kerberos Authentication Service + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kerberos Authentication Service" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kerberos Authentication Service'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-450" + Task = "Ensure 'Kerberos Service Ticket Operations' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Kerberos Service Ticket Operations + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kerberos Service Ticket Operations" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kerberos Service Ticket Operations'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-451" + Task = "Ensure 'Computer Account Management' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Computer Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Computer Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Computer Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-452" + Task = "Ensure 'Other Account Management Events' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-457" + Task = "Ensure 'Directory Service Access' is set to 'Failure'." + Test = { + # Get the audit policy for the subcategory Directory Service Access + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Access" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Access'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "AuditPolicy-458" + Task = "Ensure 'Directory Service Changes' is set to 'Success'." + Test = { + # Get the audit policy for the subcategory Directory Service Changes + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Changes" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Changes'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#RegistrySettings.ps1 new file mode 100644 index 0000000..b73308f --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#RegistrySettings.ps1 @@ -0,0 +1,9699 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +[AuditTest] @{ + Id = "Registry-001" + Task = "Ensure 'Remove `"Run this time`" button for outdated ActiveX controls in Internet Explorer ' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "RunThisTimeEnabled" ` + | Select-Object -ExpandProperty "RunThisTimeEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-002" + Task = "Ensure 'Turn off blocking of outdated ActiveX controls for Internet Explorer' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Ext" ` + -Name "VersionCheckEnabled" ` + | Select-Object -ExpandProperty "VersionCheckEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-003" + Task = "Ensure 'Allow software to run or install even if the signature is invalid' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "RunInvalidSignatures" ` + | Select-Object -ExpandProperty "RunInvalidSignatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-004" + Task = "Set registry value 'CheckExeSignatures' to yes." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Download" ` + -Name "CheckExeSignatures" ` + | Select-Object -ExpandProperty "CheckExeSignatures" + + if ($regValue -ne "yes") { + return @{ + Message = "Registry value is '$regValue'. Expected: yes" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-005" + Task = "Ensure 'Turn on 64-bit tab processes when running in Enhanced Protected Mode on 64-bit versions of Windows' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation64Bit" ` + | Select-Object -ExpandProperty "Isolation64Bit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-006" + Task = "Ensure 'Do not allow ActiveX controls to run in Protected Mode when Enhanced Protected Mode is enabled' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "DisableEPMCompat" ` + | Select-Object -ExpandProperty "DisableEPMCompat" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-007" + Task = "Set registry value 'Isolation' to PMEM." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "Isolation" ` + | Select-Object -ExpandProperty "Isolation" + + if ($regValue -ne "PMEM") { + return @{ + Message = "Registry value is '$regValue'. Expected: PMEM" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-008" + Task = "Set registry value '(Reserved)' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-009" + Task = "Set registry value 'iexplore.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-010" + Task = "Set registry value 'explorer.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DISABLE_MK_PROTOCOL" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-011" + Task = "Set registry value 'explorer.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-012" + Task = "Set registry value 'iexplore.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-013" + Task = "Set registry value '(Reserved)' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-014" + Task = "Set registry value 'explorer.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-015" + Task = "Set registry value 'iexplore.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-016" + Task = "Set registry value '(Reserved)' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-017" + Task = "Set registry value '(Reserved)' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-018" + Task = "Set registry value 'explorer.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-019" + Task = "Set registry value 'iexplore.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_ACTIVEXINSTALL" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-020" + Task = "Set registry value '(Reserved)' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-021" + Task = "Set registry value 'iexplore.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-022" + Task = "Set registry value 'explorer.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_RESTRICT_FILEDOWNLOAD" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-023" + Task = "Set registry value '(Reserved)' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-024" + Task = "Set registry value 'iexplore.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-025" + Task = "Set registry value 'explorer.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SECURITYBAND" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-026" + Task = "Set registry value 'iexplore.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-027" + Task = "Set registry value '(Reserved)' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-028" + Task = "Set registry value 'explorer.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOW_RESTRICTIONS" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-029" + Task = "Set registry value '(Reserved)' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "(Reserved)" ` + | Select-Object -ExpandProperty "(Reserved)" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-030" + Task = "Set registry value 'explorer.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "explorer.exe" ` + | Select-Object -ExpandProperty "explorer.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-031" + Task = "Set registry value 'iexplore.exe' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION" ` + -Name "iexplore.exe" ` + | Select-Object -ExpandProperty "iexplore.exe" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-032" + Task = "Set registry value 'PreventOverrideAppRepUnknown' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverrideAppRepUnknown" ` + | Select-Object -ExpandProperty "PreventOverrideAppRepUnknown" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-033" + Task = "Set registry value 'PreventOverride' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "PreventOverride" ` + | Select-Object -ExpandProperty "PreventOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-034" + Task = "Ensure 'Prevent managing SmartScreen Filter' is set to 'On'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\PhishingFilter" ` + -Name "EnabledV9" ` + | Select-Object -ExpandProperty "EnabledV9" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-035" + Task = "Set registry value 'NoCrashDetection' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Restrictions" ` + -Name "NoCrashDetection" ` + | Select-Object -ExpandProperty "NoCrashDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-036" + Task = "Ensure 'Turn off the Security Settings Check feature' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security" ` + -Name "DisableSecuritySettingsCheck" ` + | Select-Object -ExpandProperty "DisableSecuritySettingsCheck" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-037" + Task = "Ensure 'Prevent per-user installation of ActiveX controls' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Security\ActiveX" ` + -Name "BlockNonAdminActiveXInstall" ` + | Select-Object -ExpandProperty "BlockNonAdminActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-038" + Task = "Ensure 'Specify use of ActiveX Installer Service for installation of ActiveX controls' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\AxInstaller" ` + -Name "OnlyUseAXISForActiveXInstall" ` + | Select-Object -ExpandProperty "OnlyUseAXISForActiveXInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-039" + Task = "Set registry value 'Security_zones_map_edit' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_zones_map_edit" ` + | Select-Object -ExpandProperty "Security_zones_map_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-040" + Task = "Set registry value 'Security_options_edit' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_options_edit" ` + | Select-Object -ExpandProperty "Security_options_edit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-041" + Task = "Set registry value 'Security_HKLM_only' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "Security_HKLM_only" ` + | Select-Object -ExpandProperty "Security_HKLM_only" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-042" + Task = "Ensure 'Check for server certificate revocation' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "CertificateRevocation" ` + | Select-Object -ExpandProperty "CertificateRevocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-043" + Task = "Ensure 'Prevent ignoring certificate errors' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "PreventIgnoreCertErrors" ` + | Select-Object -ExpandProperty "PreventIgnoreCertErrors" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-044" + Task = "Set registry value 'WarnOnBadCertRecving' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "WarnOnBadCertRecving" ` + | Select-Object -ExpandProperty "WarnOnBadCertRecving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-045" + Task = "Ensure 'Allow fallback to SSL 3.0 (Internet Explorer)' is set to 'No Sites'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "EnableSSL3Fallback" ` + | Select-Object -ExpandProperty "EnableSSL3Fallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-046" + Task = "Ensure 'Turn off encryption support' is set to 'Use TLS 1.1 and TLS 1.2'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" ` + -Name "SecureProtocols" ` + | Select-Object -ExpandProperty "SecureProtocols" + + if ($regValue -ne 2560) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2560" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-047" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-048" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-049" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-050" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Lockdown_Zones\3]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\3" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-051" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Lockdown_Zones\4]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-052" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-053" + Task = "Ensure 'Intranet Sites: Include all network paths (UNCs)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap" ` + -Name "UNCAsIntranet" ` + | Select-Object -ExpandProperty "UNCAsIntranet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-054" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-055" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-056" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-057" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-058" + Task = "Ensure 'Java permissions' is set to 'High safety'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-059" + Task = "Ensure 'Java permissions' is set to 'High safety'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-060" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-061" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-062" + Task = "Ensure 'Run .NET Framework-reliant components signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-063" + Task = "Ensure 'Allow script-initiated windows without size or position constraints' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-064" + Task = "Ensure 'Allow drag and drop or copy and paste files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-065" + Task = "Ensure 'Include local path when user is uploading files to a server' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-066" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-067" + Task = "Ensure 'Access data sources across domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-068" + Task = "Ensure 'Launching applications and files in an IFRAME' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-069" + Task = "Ensure 'Automatic prompting for file downloads' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-070" + Task = "Ensure 'Allow scriptlets' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-071" + Task = "Ensure 'Allow scripting of Internet Explorer WebBrowser controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-072" + Task = "Ensure 'Use Pop-up Blocker' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-073" + Task = "Ensure 'Turn on Protected Mode' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-074" + Task = "Ensure 'Allow updates to status bar via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-075" + Task = "Ensure 'Userdata persistence' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-076" + Task = "Ensure 'Allow loading of XAML files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-077" + Task = "Ensure 'Run .NET Framework-reliant components not signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-078" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-079" + Task = "Ensure 'Download signed ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-080" + Task = "Ensure 'Logon options' is set to 'Prompt for user name and password'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 65536) { + return @{ + Message = "Registry value is '$regValue'. Expected: 65536" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-081" + Task = "Ensure 'Enable dragging of content from different domains within a window' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-082" + Task = "Ensure 'Download unsigned ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-083" + Task = "Ensure 'Allow only approved domains to use ActiveX controls without prompt' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-084" + Task = "Ensure 'Allow cut, copy or paste operations from the clipboard via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-085" + Task = "Ensure 'Turn on Cross-Site Scripting Filter' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-086" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-087" + Task = "Ensure 'Navigate windows and frames across different domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-088" + Task = "Ensure 'Enable dragging of content from different domains across windows' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-089" + Task = "Ensure 'Web sites in less privileged Web content zones can navigate into this zone' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-090" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Zones\3]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-091" + Task = "Ensure 'Show security warning for potentially unsafe files' is set to 'Prompt'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-092" + Task = "Ensure 'Allow only approved domains to use the TDC ActiveX control' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "120c" ` + | Select-Object -ExpandProperty "120c" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-093" + Task = "Set registry value '140C' to 3." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" ` + -Name "140C" ` + | Select-Object -ExpandProperty "140C" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-094" + Task = "Ensure 'Allow META REFRESH' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1608" ` + | Select-Object -ExpandProperty "1608" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-095" + Task = "Ensure 'Initialize and script ActiveX controls not marked as safe' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1201" ` + | Select-Object -ExpandProperty "1201" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-096" + Task = "Ensure 'Download signed ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1001" ` + | Select-Object -ExpandProperty "1001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-097" + Task = "Ensure 'Navigate windows and frames across different domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1607" ` + | Select-Object -ExpandProperty "1607" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-098" + Task = "Ensure 'Allow only approved domains to use ActiveX controls without prompt' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120b" ` + | Select-Object -ExpandProperty "120b" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-099" + Task = "Ensure 'Use Pop-up Blocker' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1809" ` + | Select-Object -ExpandProperty "1809" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-100" + Task = "Ensure 'Download unsigned ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1004" ` + | Select-Object -ExpandProperty "1004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-101" + Task = "Ensure 'Userdata persistence' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1606" ` + | Select-Object -ExpandProperty "1606" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-102" + Task = "Ensure 'Allow cut, copy or paste operations from the clipboard via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1407" ` + | Select-Object -ExpandProperty "1407" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-103" + Task = "Ensure 'Include local path when user is uploading files to a server' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "160A" ` + | Select-Object -ExpandProperty "160A" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-104" + Task = "Ensure 'Access data sources across domains' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1406" ` + | Select-Object -ExpandProperty "1406" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-105" + Task = "Ensure 'Allow script-initiated windows without size or position constraints' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2102" ` + | Select-Object -ExpandProperty "2102" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-106" + Task = "Ensure 'Run .NET Framework-reliant components not signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2004" ` + | Select-Object -ExpandProperty "2004" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-107" + Task = "Ensure 'Automatic prompting for file downloads' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2200" ` + | Select-Object -ExpandProperty "2200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-108" + Task = "Ensure 'Allow binary and script behaviors' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2000" ` + | Select-Object -ExpandProperty "2000" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-109" + Task = "Ensure 'Scripting of Java applets' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1402" ` + | Select-Object -ExpandProperty "1402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-110" + Task = "Ensure 'Allow file downloads' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1803" ` + | Select-Object -ExpandProperty "1803" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-111" + Task = "Ensure 'Allow loading of XAML files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2402" ` + | Select-Object -ExpandProperty "2402" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-112" + Task = "Ensure 'Allow active scripting' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1400" ` + | Select-Object -ExpandProperty "1400" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-113" + Task = "Ensure 'Logon options' is set to 'Anonymous logon'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1A00" ` + | Select-Object -ExpandProperty "1A00" + + if ($regValue -ne 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-114" + Task = "Ensure 'Run .NET Framework-reliant components signed with Authenticode' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2001" ` + | Select-Object -ExpandProperty "2001" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-115" + Task = "Ensure 'Turn on Protected Mode' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2500" ` + | Select-Object -ExpandProperty "2500" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-116" + Task = "Ensure 'Turn on Cross-Site Scripting Filter' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1409" ` + | Select-Object -ExpandProperty "1409" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-117" + Task = "Ensure 'Java permissions' is set to 'Disable Java'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1C00" ` + | Select-Object -ExpandProperty "1C00" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-118" + Task = "Ensure 'Allow scriptlets' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1209" ` + | Select-Object -ExpandProperty "1209" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-119" + Task = "Ensure 'Don't run antimalware programs against ActiveX controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "270C" ` + | Select-Object -ExpandProperty "270C" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-120" + Task = "Ensure 'Allow scripting of Internet Explorer WebBrowser controls' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1206" ` + | Select-Object -ExpandProperty "1206" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-121" + Task = "Ensure 'Enable dragging of content from different domains within a window' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2708" ` + | Select-Object -ExpandProperty "2708" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-122" + Task = "Ensure 'Allow drag and drop or copy and paste files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1802" ` + | Select-Object -ExpandProperty "1802" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-123" + Task = "Ensure 'Allow updates to status bar via script' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2103" ` + | Select-Object -ExpandProperty "2103" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-124" + Task = "Ensure 'Enable dragging of content from different domains across windows' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2709" ` + | Select-Object -ExpandProperty "2709" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-125" + Task = "Ensure 'Script ActiveX controls marked safe for scripting' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1405" ` + | Select-Object -ExpandProperty "1405" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-126" + Task = "Ensure 'Web sites in less privileged Web content zones can navigate into this zone' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2101" ` + | Select-Object -ExpandProperty "2101" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-127" + Task = "Ensure 'Turn on SmartScreen Filter scan' is set to 'Enable'. [Zones\4]" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "2301" ` + | Select-Object -ExpandProperty "2301" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-128" + Task = "Ensure 'Run ActiveX controls and plugins' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1200" ` + | Select-Object -ExpandProperty "1200" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-129" + Task = "Ensure 'Launching applications and files in an IFRAME' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1804" ` + | Select-Object -ExpandProperty "1804" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-130" + Task = "Ensure 'Show security warning for potentially unsafe files' is set to 'Disable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "1806" ` + | Select-Object -ExpandProperty "1806" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-131" + Task = "Ensure 'Allow only approved domains to use the TDC ActiveX control' is set to 'Enable'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "120c" ` + | Select-Object -ExpandProperty "120c" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-132" + Task = "Set registry value '140C' to 3." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" ` + -Name "140C" ` + | Select-Object -ExpandProperty "140C" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-133" + Task = "Ensure 'Turn off Autoplay' is set to 'All drives'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-134" + Task = "Ensure 'Set the default behavior for AutoRun' is set to 'Do not execute any autorun commands'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-135" + Task = "Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-136" + Task = "Set registry value 'LocalAccountTokenFilterPolicy' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-143" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '32768'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-153" + Task = "Set registry value 'NoLockScreenCamera' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-157" + Task = "Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-169" + Task = "Ensure 'Restrict Unauthenticated RPC clients' is set to 'Authenticated'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-186" + Task = "Set registry value 'AdmPwdEnabled' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft Services\AdmPwd" ` + -Name "AdmPwdEnabled" ` + | Select-Object -ExpandProperty "AdmPwdEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-197" + Task = "Set registry value 'RestrictRemoteSAM' to O:BAG:BAD:(A;;RC;;;BA)." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictRemoteSAM" ` + | Select-Object -ExpandProperty "RestrictRemoteSAM" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-198" + Task = "Set registry value 'EnablePlainTextPassword' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-199" + Task = "Set registry value 'NoLMHash' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-200" + Task = "Set registry value 'LimitBlankPasswordUse' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-201" + Task = "Set registry value 'ProtectionMode' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-202" + Task = "Set registry value 'RestrictAnonymous' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-203" + Task = "Set registry value 'RestrictNullSessAccess' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-204" + Task = "Set registry value 'RestrictAnonymousSAM' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-205" + Task = "Set registry value 'requirestrongkey' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "requirestrongkey" ` + | Select-Object -ExpandProperty "requirestrongkey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-206" + Task = "Set registry value 'requiresecuritysignature' to 1." + Test = { + try { + if((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Registry-207" + Task = "Set registry value 'RequireSecuritySignature' to 1." + Test = { + try { + if((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True){ + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try{ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "Registry-208" + Task = "Set registry value 'signsecurechannel' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "signsecurechannel" ` + | Select-Object -ExpandProperty "signsecurechannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-277" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled with UEFI lock'. (Member Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-279" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-280" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Secure Boot'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if ($regValue -eq 3) { + return @{ + Message = "Set to 'Secure Boot and DMA Protection' which is more secure." + Status = "True" + } + } + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-281" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Enabled with UEFI lock'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-282" + Task = "Set registry value 'HVCIMATRequired' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HVCIMATRequired" ` + | Select-Object -ExpandProperty "HVCIMATRequired" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-283" + Task = "Ensure 'Turn On Virtualization Based Security' is set to 'Disabled'. (Domain Controller)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-284" + Task = "Ensure 'Turn On Virtualization Based Security: Secure Launch Configuration' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureSystemGuardLaunch" ` + | Select-Object -ExpandProperty "ConfigureSystemGuardLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-285" + Task = "Set registry value 'PUAProtection' to 1." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-286" + Task = "Set registry value 'MpCloudBlockLevel' to 2." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\MpEngine" ` + -Name "MpCloudBlockLevel" ` + | Select-Object -ExpandProperty "MpCloudBlockLevel" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-287" + Task = "Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-288" + Task = "Ensure 'Turn off real-time protection' is set to 'Disabled'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-289" + Task = "Ensure 'Turn on script scanning' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableScriptScanning" ` + | Select-Object -ExpandProperty "DisableScriptScanning" + + if (($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-290" + Task = "Ensure 'Scan removable drives' is set to 'Enabled'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-291" + Task = "Ensure 'Send file samples when further analysis is required' is set to 'Send safe samples'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SubmitSamplesConsent" ` + | Select-Object -ExpandProperty "SubmitSamplesConsent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-292" + Task = "Ensure 'Join Microsoft MAPS' is set to 'Advanced MAPS'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-293" + Task = "Ensure 'Configure the 'Block at First Sight' feature' is set to 'Enabled'." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "DisableBlockAtFirstSeen" ` + | Select-Object -ExpandProperty "DisableBlockAtFirstSeen" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-294" + Task = "Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-295" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from injecting code into other processes)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-296" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from creating executable content)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-297" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from creating child processes)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-298" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Win32 API calls from Office macro)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-299" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block execution of potentially obfuscated scripts)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-300" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block JavaScript or VBScript from launching downloaded executable content)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-301" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block executable content from email client and webmail)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-302" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block credential stealing from the Windows local security authority subsystem (lsass.exe))" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-303" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block untrusted and unsigned processes that run from USB)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-304" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office communication application from creating child processes)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-305" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Adobe Reader from creating child processes)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-306" + Task = "Ensure 'Configure Attack Surface Reduction rules' is configured (Use advanced protection against ransomware)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "c1db55ab-c21a-4637-bb3f-a12568109d35" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "c1db55ab-c21a-4637-bb3f-a12568109d35" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-307" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block persistence through WMI event subscription)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if($asrTest1){ + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if($asrTest2){ + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-308" + Task = "Set registry value 'EnableNetworkProtection' to 1." + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-316" + Task = "Set registry value 'FormSuggest Passwords' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Control Panel" ` + -Name "FormSuggest Passwords" ` + | Select-Object -ExpandProperty "FormSuggest Passwords" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-317" + Task = "Ensure 'Turn on the auto-complete feature for user names and passwords on forms' is set to 'no'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "FormSuggest PW Ask" ` + | Select-Object -ExpandProperty "FormSuggest PW Ask" + + if ($regValue -ne "no") { + return @{ + Message = "Registry value is '$regValue'. Expected: no" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-318" + Task = "Set registry value 'FormSuggest Passwords' to no." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main" ` + -Name "FormSuggest Passwords" ` + | Select-Object -ExpandProperty "FormSuggest Passwords" + + if ($regValue -ne "no") { + return @{ + Message = "Registry value is '$regValue'. Expected: no" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-322" + Task = "Set registry value 'AllowEncryptionOracle' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-323" + Task = "Set registry value 'EnhancedAntiSpoofing' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-324" + Task = "Ensure 'Prevent downloading of enclosures' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-325" + Task = "Set registry value 'AllowProtectedCreds' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-326" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '32768'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 32768) { + return @{ + Message = "Registry value is '$regValue'. Expected: 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-327" + Task = "Ensure 'Specify the maximum log file size (KB)' is set to '196608'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if ($regValue -ne 196608) { + return @{ + Message = "Registry value is '$regValue'. Expected: 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-329" + Task = "Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-330" + Task = "Ensure 'Configure registry policy processing' is set to '0'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-331" + Task = "Ensure 'Configure registry policy processing' is set to '0'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-332" + Task = "Set registry value 'AlwaysInstallElevated' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-333" + Task = "Ensure 'Allow user control over installs' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-334" + Task = "Set registry value 'DeviceEnumerationPolicy' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-335" + Task = "Ensure 'Enable insecure guest logons' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-336" + Task = "Set registry value '\\*\NETLOGON' to RequireMutualAuthentication=1, RequireIntegrity=1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-337" + Task = "Set registry value '\\*\SYSVOL' to RequireMutualAuthentication=1, RequireIntegrity=1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if($regValue -eq $null){ + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object{ $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-339" + Task = "Set registry value 'NoLockScreenSlideshow' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-340" + Task = "Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-341" + Task = "Ensure 'Turn on PowerShell Script Block Logging' is not set." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockInvocationLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockInvocationLogging" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-343" + Task = "Set registry value 'EnforcementMode' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\SrpV2\Appx" ` + -Name "EnforcementMode" ` + | Select-Object -ExpandProperty "EnforcementMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-358" + Task = "Ensure 'Configure Windows SmartScreen' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-359" + Task = "Set registry value 'ShellSmartScreenLevel' to Block." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-360" + Task = "Set registry value 'AllowIndexingEncryptedStoresOrItems' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-361" + Task = "Ensure 'Allow Basic authentication' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-362" + Task = "Ensure 'Allow unencrypted traffic' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-363" + Task = "Ensure 'Disallow Digest authentication' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-364" + Task = "Ensure 'Allow Basic authentication' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-365" + Task = "Ensure 'Allow unencrypted traffic' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-366" + Task = "Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-367" + Task = "Ensure 'Turn off multicast name resolution' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-368" + Task = "Ensure 'Limits print driver installation to Administrators' is set to 'Enabled' (Automated)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "RestrictDriverInstallationToAdministrators" ` + | Select-Object -ExpandProperty "RestrictDriverInstallationToAdministrators" + + if (($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-369" + Task = "Set registry value 'DisablePasswordSaving' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-370" + Task = "Set registry value 'fDisableCdm' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-371" + Task = "Set registry value 'fPromptForPassword' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-372" + Task = "Set registry value 'fEncryptRPCTraffic' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-373" + Task = "Set registry value 'MinEncryptionLevel' to 3." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-375" + Task = "Domain: Set registry value 'DefaultOutboundAction' to 0." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-376" + Task = "Domain: Set registry value 'DefaultInboundAction' to 1." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-377" + Task = "Domain: Set registry value 'EnableFirewall' to 1." + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller"} + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-378" + Task = "Private: Set registry value 'EnableFirewall' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-379" + Task = "Private: Set registry value 'DefaultInboundAction' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-380" + Task = "Private: Set registry value 'DefaultOutboundAction' to 0." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-381" + Task = "Public: Set registry value 'EnableFirewall' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-382" + Task = "Public: Set registry value 'DefaultOutboundAction' to 0." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultOutboundAction" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-383" + Task = "Public: Set registry value 'DefaultInboundAction' to 1." + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "Registry-384" + Task = "Ensure 'Allow Windows Ink Workspace' is set to 'On, but disallow access above lock'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-385" + Task = "Ensure 'WDigest Authentication (disabling may require KB2871997)' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-386" + Task = "Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-387" + Task = "Set registry value 'DriverLoadPolicy' to 3." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-388" + Task = "Ensure 'Configure SMB v1 server' is set to 'Disabled'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-389" + Task = "Ensure 'Configure SMB v1 client driver' is set to 'Disable driver (recommended)'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MrxSmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-390" + Task = "Set registry value 'NoNameReleaseOnDemand' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NoNameReleaseOnDemand" ` + | Select-Object -ExpandProperty "NoNameReleaseOnDemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-391" + Task = "Set registry value 'NodeType' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-392" + Task = "Set registry value 'EnableICMPRedirect' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-393" + Task = "Set registry value 'DisableIPSourceRouting' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-394" + Task = "Set registry value 'DisableIPSourceRouting' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-395" + Task = "Set registry value 'allownullsessionfallback' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "allownullsessionfallback" ` + | Select-Object -ExpandProperty "allownullsessionfallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-396" + Task = "Set registry value 'InactivityTimeoutSecs' to 900." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if ($regValue -ne 900) { + return @{ + Message = "Registry value is '$regValue'. Expected: 900" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-397" + Task = "Set registry value 'ScRemoveOption' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -ne "1") { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-398" + Task = "Set registry value 'SCENoApplyLegacyAuditPolicy' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-399" + Task = "Set registry value 'EnableVirtualization' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-400" + Task = "Set registry value 'FilterAdministratorToken' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-401" + Task = "Set registry value 'EnableLUA' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-402" + Task = "Set registry value 'EnableInstallerDetection' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-403" + Task = "Set registry value 'ConsentPromptBehaviorAdmin' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-404" + Task = "Set registry value 'ConsentPromptBehaviorUser' to 0." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-405" + Task = "Set registry value 'EnableSecureUIAPaths' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-406" + Task = "Set registry value 'LDAPClientIntegrity' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-407" + Task = "Set registry value 'LmCompatibilityLevel' to 5." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-408" + Task = "Set registry value 'NTLMMinClientSec' to 537395200." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-409" + Task = "Set registry value 'sealsecurechannel' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "sealsecurechannel" ` + | Select-Object -ExpandProperty "sealsecurechannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-410" + Task = "Set registry value 'NTLMMinServerSec' to 537395200." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-411" + Task = "Set registry value 'requiresignorseal' to 1." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "requiresignorseal" ` + | Select-Object -ExpandProperty "requiresignorseal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-423" + Task = "Set registry value 'LDAPServerIntegrity' to 2." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LDAPServerIntegrity" ` + | Select-Object -ExpandProperty "LDAPServerIntegrity" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "Registry-424" + Task = "Ensure 'Extended Protection for LDAP Authentication (Domain Controllers only)' is set to 'Enabled, always (recommended)'." + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LdapEnforceChannelBinding" ` + | Select-Object -ExpandProperty "LdapEnforceChannelBinding" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#SecurityOptions.ps1 new file mode 100644 index 0000000..e074f0b --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#SecurityOptions.ps1 @@ -0,0 +1,26 @@ +[AuditTest] @{ + Id = "SecurityOption-226" + Task = "Ensure 'LSAAnonymousNameLookup' is set to '0'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#UserRights.ps1 new file mode 100644 index 0000000..54d4535 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2022-Microsoft-FINAL#UserRights.ps1 @@ -0,0 +1,925 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE"){ + if ($name -eq "Enterprise Admins"){ + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins"){ + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and $hyperVStatus -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "UserRight-227" + Task = "Ensure 'SeSecurityPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-228" + Task = "Ensure 'SeCreateTokenPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-230" + Task = "Ensure 'SeCreatePagefilePrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-231" + Task = "Ensure 'SeRemoteShutdownPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-232" + Task = "Ensure 'SeLoadDriverPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-233" + Task = "Ensure 'SeRestorePrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-234" + Task = "Ensure 'SeCreateGlobalPrivilege' is set to 'S-1-5-20, S-1-5-19, S-1-5-6, S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-20" + "S-1-5-19" + "S-1-5-6" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-235" + Task = "Ensure 'SeManageVolumePrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-236" + Task = "Ensure 'SeInteractiveLogonRight' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-237" + Task = "Ensure 'SeEnableDelegationPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-238" + Task = "Ensure 'SeCreatePermanentPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-239" + Task = "Ensure 'SeDebugPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + #No UserRights on System comparing to publisher recommendation + if($null -eq $currentUserRights -and $identityAccounts.Count -gt 0){ + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if($currentUserRights.Count -lt $identityAccounts.Count){ + $users = "" + foreach($currentUser in $currentUserRights){ + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-240" + Task = "Ensure 'SeProfileSingleProcessPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-241" + Task = "Ensure 'SeBackupPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-242" + Task = "Ensure 'SeNetworkLogonRight' is set to 'S-1-5-11, S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-11" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-243" + Task = "Ensure 'SeDenyNetworkLogonRight' is set to 'S-1-5-114'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-114" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeDenyNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-244" + Task = "Ensure 'SeImpersonatePrivilege' is set to 'S-1-5-20, S-1-5-19, S-1-5-6, S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-20" + "S-1-5-19" + "S-1-5-6" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-245" + Task = "Ensure 'SeSystemEnvironmentPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-246" + Task = "Ensure 'SeLockMemoryPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-247" + Task = "Ensure 'SeTcbPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-248" + Task = "Ensure 'SeTakeOwnershipPrivilege' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-249" + Task = "Ensure 'SeDenyRemoteInteractiveLogonRight' is set to 'S-1-5-113'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeDenyRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-428" + Task = "Ensure 'SeTrustedCredManAccessPrivilege' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "UserRight-429" + Task = "Ensure 'SeRemoteInteractiveLogonRight' is set to 'S-1-5-32-544'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#AccountPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#AccountPolicies.ps1 new file mode 100644 index 0000000..57095cb --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#AccountPolicies.ps1 @@ -0,0 +1,257 @@ +[AuditTest] @{ + Id = "1.1.1" + Task = "(L1) Ensure 'Enforce password history' is set to '24 or more password(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordHistorySize"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 24) { + return @{ + Message = "'PasswordHistorySize' currently set to: $setPolicy. Expected: 24" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "(L1) Ensure 'Maximum password age' is set to '365 or fewer days, but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MaximumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -gt 365 -or $setPolicy -le 0){ + if ($setPolicy -eq -1) { + #Setting 0 in GroupPolicy translates to -1 in AuditPolicy + $setPolicy = "Password never expires" + } + return @{ + Message = "'MaximumPasswordAge' currently set to: $setPolicy. Expected: x <= 365 days and x > 0 days" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "(L1) Ensure 'Minimum password age' is set to '1 or more day(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordAge"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -lt 1 ) { + return @{ + Message = "'MinimumPasswordAge' currently set to: $setPolicy. Expected: x >= 1 days" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "(L1) Ensure 'Minimum password length' is set to '14 or more character(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["MinimumPasswordLength"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -lt 14)) { + return @{ + Message = "'MinimumPasswordLength' currently set to: $setPolicy. Expected: x >= 14" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.5" + Task = "(L1) Ensure 'Password must meet complexity requirements' is set to 'Enabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["PasswordComplexity"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 1) { + return @{ + Message = "'PasswordComplexity' currently set to: $setPolicy. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.7" + Task = "(L1) Ensure 'Store passwords using reversible encryption' is set to 'Disabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "(L1) Ensure 'Account lockout duration' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutDuration"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -lt 15 -or $setPolicy -gt 99999 ) { + return @{ + Message = "'LockoutDuration' currently set to: $setPolicy. Expected: x >= 15 minutes and x <= 99999 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "(L1) Ensure 'Account lockout threshold' is set to '5 or fewer invalid logon attempt(s), but not 0'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["LockoutBadCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 5 -or $setPolicy -le 0)) { + return @{ + Message = "'LockoutBadCount' currently set to: $setPolicy. Expected: x <= 5 and x > 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.4" + Task = "(L1) Ensure 'Reset account lockout counter after' is set to '15 or more minute(s)'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ResetLockoutCount"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if (($setPolicy -gt 99999 -or $setPolicy -lt 15 )) { + return @{ + Message = "'ResetLockoutCount' currently set to: $setPolicy. Expected: x <= 99999 minutes and x >= 15 minutes" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} + diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#AuditPolicies.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#AuditPolicies.ps1 new file mode 100644 index 0000000..3ae6c46 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#AuditPolicies.ps1 @@ -0,0 +1,2036 @@ +# Common +function Get-AuditPolicySubcategoryGUID { + Param( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string] $Subcategory + ) + + $map = @{ + "Security State Change" = "{0CCE9210-69AE-11D9-BED3-505054503030}" + "Security System Extension" = "{0CCE9211-69AE-11D9-BED3-505054503030}" + "System Integrity" = "{0CCE9212-69AE-11D9-BED3-505054503030}" + "IPsec Driver" = "{0CCE9213-69AE-11D9-BED3-505054503030}" + "Other System Events" = "{0CCE9214-69AE-11D9-BED3-505054503030}" + "Logon" = "{0CCE9215-69AE-11D9-BED3-505054503030}" + "Logoff" = "{0CCE9216-69AE-11D9-BED3-505054503030}" + "Account Lockout" = "{0CCE9217-69AE-11D9-BED3-505054503030}" + "IPsec Main Mode" = "{0CCE9218-69AE-11D9-BED3-505054503030}" + "IPsec Quick Mode" = "{0CCE9219-69AE-11D9-BED3-505054503030}" + "IPsec Extended Mode" = "{0CCE921A-69AE-11D9-BED3-505054503030}" + "Special Logon" = "{0CCE921B-69AE-11D9-BED3-505054503030}" + "Other Logon/Logoff Events" = "{0CCE921C-69AE-11D9-BED3-505054503030}" + "Network Policy Server" = "{0CCE9243-69AE-11D9-BED3-505054503030}" + "User / Device Claims" = "{0CCE9247-69AE-11D9-BED3-505054503030}" + "Group Membership" = "{0CCE9249-69AE-11D9-BED3-505054503030}" + "File System" = "{0CCE921D-69AE-11D9-BED3-505054503030}" + "Registry" = "{0CCE921E-69AE-11D9-BED3-505054503030}" + "Kernel Object" = "{0CCE921F-69AE-11D9-BED3-505054503030}" + "SAM" = "{0CCE9220-69AE-11D9-BED3-505054503030}" + "Certification Services" = "{0CCE9221-69AE-11D9-BED3-505054503030}" + "Application Generated" = "{0CCE9222-69AE-11D9-BED3-505054503030}" + "Handle Manipulation" = "{0CCE9223-69AE-11D9-BED3-505054503030}" + "File Share" = "{0CCE9224-69AE-11D9-BED3-505054503030}" + "Filtering Platform Packet Drop" = "{0CCE9225-69AE-11D9-BED3-505054503030}" + "Filtering Platform Connection" = "{0CCE9226-69AE-11D9-BED3-505054503030}" + "Other Object Access Events" = "{0CCE9227-69AE-11D9-BED3-505054503030}" + "Detailed File Share" = "{0CCE9244-69AE-11D9-BED3-505054503030}" + "Removable Storage" = "{0CCE9245-69AE-11D9-BED3-505054503030}" + "Central Policy Staging" = "{0CCE9246-69AE-11D9-BED3-505054503030}" + "Sensitive Privilege Use" = "{0CCE9228-69AE-11D9-BED3-505054503030}" + "Non Sensitive Privilege Use" = "{0CCE9229-69AE-11D9-BED3-505054503030}" + "Other Privilege Use Events" = "{0CCE922A-69AE-11D9-BED3-505054503030}" + "Process Creation" = "{0CCE922B-69AE-11D9-BED3-505054503030}" + "Process Termination" = "{0CCE922C-69AE-11D9-BED3-505054503030}" + "DPAPI Activity" = "{0CCE922D-69AE-11D9-BED3-505054503030}" + "RPC Events" = "{0CCE922E-69AE-11D9-BED3-505054503030}" + "Plug and Play Events" = "{0CCE9248-69AE-11D9-BED3-505054503030}" + "Token Right Adjusted Events" = "{0CCE924A-69AE-11D9-BED3-505054503030}" + "Audit Policy Change" = "{0CCE922F-69AE-11D9-BED3-505054503030}" + "Authentication Policy Change" = "{0CCE9230-69AE-11D9-BED3-505054503030}" + "Authorization Policy Change" = "{0CCE9231-69AE-11D9-BED3-505054503030}" + "MPSSVC Rule-Level Policy Change" = "{0CCE9232-69AE-11D9-BED3-505054503030}" + "Filtering Platform Policy Change" = "{0CCE9233-69AE-11D9-BED3-505054503030}" + "Other Policy Change Events" = "{0CCE9234-69AE-11D9-BED3-505054503030}" + "User Account Management" = "{0CCE9235-69AE-11D9-BED3-505054503030}" + "Computer Account Management" = "{0CCE9236-69AE-11D9-BED3-505054503030}" + "Security Group Management" = "{0CCE9237-69AE-11D9-BED3-505054503030}" + "Distribution Group Management" = "{0CCE9238-69AE-11D9-BED3-505054503030}" + "Application Group Management" = "{0CCE9239-69AE-11D9-BED3-505054503030}" + "Other Account Management Events" = "{0CCE923A-69AE-11D9-BED3-505054503030}" + "Directory Service Access" = "{0CCE923B-69AE-11D9-BED3-505054503030}" + "Directory Service Changes" = "{0CCE923C-69AE-11D9-BED3-505054503030}" + "Directory Service Replication" = "{0CCE923D-69AE-11D9-BED3-505054503030}" + "Detailed Directory Service Replication" = "{0CCE923E-69AE-11D9-BED3-505054503030}" + "Credential Validation" = "{0CCE923F-69AE-11D9-BED3-505054503030}" + "Kerberos Service Ticket Operations" = "{0CCE9240-69AE-11D9-BED3-505054503030}" + "Other Account Logon Events" = "{0CCE9241-69AE-11D9-BED3-505054503030}" + "Kerberos Authentication Service" = "{0CCE9242-69AE-11D9-BED3-505054503030}" + } + + if ($map.ContainsKey($Subcategory)) { + return $map[$Subcategory] + } + return "" +} + +# Tests +[AuditTest] @{ + Id = "17.1.1" + Task = "(L1) Ensure 'Audit Credential Validation' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Credential Validation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Credential Validation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Credential Validation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.1.2" + Task = "(L1) Ensure 'Audit Kerberos Authentication Service' is set to 'Success and Failure' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Kerberos Authentication Service + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kerberos Authentication Service" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kerberos Authentication Service'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.1.3" + Task = "(L1) Ensure 'Audit Kerberos Service Ticket Operations' is set to 'Success and Failure' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Kerberos Service Ticket Operations + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Kerberos Service Ticket Operations" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Kerberos Service Ticket Operations'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.1" + Task = "(L1) Ensure 'Audit Application Group Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Application Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Application Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Application Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.2" + Task = "(L1) Ensure 'Audit Computer Account Management' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Computer Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Computer Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Computer Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.3" + Task = "(L1) Ensure 'Audit Distribution Group Management' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Distribution Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Distribution Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Distribution Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.4" + Task = "(L1) Ensure 'Audit Other Account Management Events' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Other Account Management Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Account Management Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Account Management Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.5" + Task = "(L1) Ensure 'Audit Security Group Management' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security Group Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security Group Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security Group Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.2.6" + Task = "(L1) Ensure 'Audit User Account Management' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory User Account Management + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "User Account Management" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'User Account Management'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.1" + Task = "(L1) Ensure 'Audit PNP Activity' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Plug and Play Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Plug and Play Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Plug and Play Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.3.2" + Task = "(L1) Ensure 'Audit Process Creation' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Process Creation + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Process Creation" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Process Creation'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.4.1" + Task = "(L1) Ensure 'Audit Directory Service Access' is set to include 'Failure' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Directory Service Access + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Access" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Access'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.4.2" + Task = "(L1) Ensure 'Audit Directory Service Changes' is set to include 'Success' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + # Get the audit policy for the subcategory Directory Service Changes + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Directory Service Changes" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Directory Service Changes'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.1" + Task = "(L1) Ensure 'Audit Account Lockout' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Account Lockout + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Account Lockout" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Account Lockout'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.2" + Task = "(L1) Ensure 'Audit Group Membership' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Group Membership + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Group Membership" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Group Membership'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.3" + Task = "(L1) Ensure 'Audit Logoff' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Logoff + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logoff" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logoff'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.4" + Task = "(L1) Ensure 'Audit Logon' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.5" + Task = "(L1) Ensure 'Audit Other Logon/Logoff Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Logon/Logoff Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Logon/Logoff Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Logon/Logoff Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.5.6" + Task = "(L1) Ensure 'Audit Special Logon' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Special Logon + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Special Logon" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Special Logon'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.1" + Task = "(L1) Ensure 'Audit Detailed File Share' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Detailed File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Detailed File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Detailed File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.2" + Task = "(L1) Ensure 'Audit File Share' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory File Share + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "File Share" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'File Share'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.3" + Task = "(L1) Ensure 'Audit Other Object Access Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other Object Access Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Object Access Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Object Access Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.6.4" + Task = "(L1) Ensure 'Audit Removable Storage' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Removable Storage + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Removable Storage" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Removable Storage'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.1" + Task = "(L1) Ensure 'Audit Audit Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Audit Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Audit Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Audit Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.2" + Task = "(L1) Ensure 'Audit Authentication Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authentication Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authentication Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authentication Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.3" + Task = "(L1) Ensure 'Audit Authorization Policy Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Authorization Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Authorization Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Authorization Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.4" + Task = "(L1) Ensure 'Audit MPSSVC Rule-Level Policy Change' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Mpssvc Rule-Level Policy Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Mpssvc Rule-Level Policy Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Mpssvc Rule-Level Policy Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.7.5" + Task = "(L1) Ensure 'Audit Other Policy Change Events' is set to include 'Failure'" + Test = { + # Get the audit policy for the subcategory Other Policy Change Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other Policy Change Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other Policy Change Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Failure" -and $setting -ne "Success and Failure" -And $setting -ne "Fehler" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.8.1" + Task = "(L1) Ensure 'Audit Sensitive Privilege Use' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Sensitive Privilege Use + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Sensitive Privilege Use" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Sensitive Privilege Use'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.1" + Task = "(L1) Ensure 'Audit IPsec Driver' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Ipsec Driver + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Ipsec Driver" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Ipsec Driver'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.2" + Task = "(L1) Ensure 'Audit Other System Events' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory Other System Events + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Other System Events" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Other System Events'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.3" + Task = "(L1) Ensure 'Audit Security State Change' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security State Change + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security State Change" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security State Change'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.4" + Task = "(L1) Ensure 'Audit Security System Extension' is set to include 'Success'" + Test = { + # Get the audit policy for the subcategory Security System Extension + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "Security System Extension" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'Security System Extension'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success" -and $setting -ne "Success and Failure" -And $setting -ne "Erfolg" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "17.9.5" + Task = "(L1) Ensure 'Audit System Integrity' is set to 'Success and Failure'" + Test = { + # Get the audit policy for the subcategory System Integrity + $subCategoryGUID = Get-AuditPolicySubcategoryGUID -Subcategory "System Integrity" + + if ([string]::IsNullOrEmpty($subCategoryGUID)) { + return @{ + Message = "Cannot get Subcategory 'System Integrity'" + Status = "None" + } + } + + $auditPolicyString = auditpol /get /subcategory:"$subCategoryGUID" + + # auditpol does not throw exceptions, so test the results and throw if needed + if ($LASTEXITCODE -ne 0) { + $errorString = "'auditpol /get /subcategory:'$subCategoryGUID' returned with exit code $LASTEXITCODE" + throw [System.ArgumentException] $errorString + Write-Error -Message $errorString + } + + if ($null -eq $auditPolicyString) { + return @{ + Status = "Warning" + Message = "Couldn't get setting. Auditpol returned nothing." + } + } + + # Remove empty lines and headers + $line = $auditPolicyString ` + | Where-Object { $_ } ` + | Select-Object -Skip 3 + + if ($line -notmatch "(No Auditing|Success and Failure|Success|Failure|Keine Überwachung|Erfolg und Fehler|Erfolg|Fehler)$") { + return @{ + Status = "Warning" + Message = "Couldn't get setting." + } + } + + $setting = $Matches[0] + + if ($setting -ne "Success and Failure" -And $setting -ne "Erfolg und Fehler") { + return @{ + Status = "False" + Message = "Set to: $setting" + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#RegistrySettings.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#RegistrySettings.ps1 new file mode 100644 index 0000000..daa3744 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#RegistrySettings.ps1 @@ -0,0 +1,14316 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +# 2025 +[AuditTest] @{ + Id = "1.1.6" + Task = "(L1) Ensure 'Relax minimum password length limits' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SAM" ` + -Name "RelaxMinimumPasswordLengthLimits" ` + | Select-Object -ExpandProperty "RelaxMinimumPasswordLengthLimits" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.2" + Task = "(L1) Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LimitBlankPasswordUse" ` + | Select-Object -ExpandProperty "LimitBlankPasswordUse" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.1" + Task = "(L1) Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "SCENoApplyLegacyAuditPolicy" ` + | Select-Object -ExpandProperty "SCENoApplyLegacyAuditPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2.2" + Task = "(L1) Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "CrashOnAuditFail" ` + | Select-Object -ExpandProperty "CrashOnAuditFail" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4.1" + Task = "(L1) Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers" ` + -Name "AddPrinterDrivers" ` + | Select-Object -ExpandProperty "AddPrinterDrivers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.1" + Task = "(L1) Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "SubmitControl" ` + | Select-Object -ExpandProperty "SubmitControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.2" + Task = "(L1) Ensure 'Domain controller: Allow vulnerable Netlogon secure channel connections' is set to 'Not Configured' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "vulnerablechannelallowlist" ` + | Select-Object -ExpandProperty "vulnerablechannelallowlist" + + return @{ + Message = "Registry value found." + Status = "False" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.3" + Task = "(L1) Ensure 'Domain controller: LDAP server channel binding token requirements' is set to 'Always' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LdapEnforceChannelBinding" ` + | Select-Object -ExpandProperty "LdapEnforceChannelBinding" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.4" + Task = "(L1) Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LDAPServerIntegrity" ` + | Select-Object -ExpandProperty "LDAPServerIntegrity" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.5" + Task = "(L1) Ensure 'Domain controller: LDAP server signing requirements Enforcement' is set to 'Enabled' (DC only)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LDAPServerEnforceIntegrity" ` + | Select-Object -ExpandProperty "LDAPServerEnforceIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.5.6" + Task = "(L1) Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled' (DC only)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RefusePasswordChange" ` + | Select-Object -ExpandProperty "RefusePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.1" + Task = "(L1) Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireSignOrSeal" ` + | Select-Object -ExpandProperty "RequireSignOrSeal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.2" + Task = "(L1) Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SealSecureChannel" ` + | Select-Object -ExpandProperty "SealSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.3" + Task = "(L1) Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "SignSecureChannel" ` + | Select-Object -ExpandProperty "SignSecureChannel" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.4" + Task = "(L1) Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "DisablePasswordChange" ` + | Select-Object -ExpandProperty "DisablePasswordChange" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.5" + Task = "(L1) Ensure 'Domain member: Maximum machine account password age' is set to '30 or fewer days, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "MaximumPasswordAge" ` + | Select-Object -ExpandProperty "MaximumPasswordAge" + + if (($regValue -le 0 -or $regValue -gt 30)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x > 0 and x <= 30" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.6.6" + Task = "(L1) Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "RequireStrongKey" ` + | Select-Object -ExpandProperty "RequireStrongKey" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.1" + Task = "(L1) Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableCAD" ` + | Select-Object -ExpandProperty "DisableCAD" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.2" + Task = "(L1) Ensure 'Interactive logon: Don't display last signed-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DontDisplayLastUserName" ` + | Select-Object -ExpandProperty "DontDisplayLastUserName" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.3" + Task = "(L1) Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "InactivityTimeoutSecs" ` + | Select-Object -ExpandProperty "InactivityTimeoutSecs" + + if (($regValue -gt 900 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.4" + Task = "(L1) Configure 'Interactive logon: Message text for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeText" ` + | Select-Object -ExpandProperty "LegalNoticeText" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.5" + Task = "(L1) Configure 'Interactive logon: Message title for users attempting to log on'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LegalNoticeCaption" ` + | Select-Object -ExpandProperty "LegalNoticeCaption" + + $regValue = $regValue.Trim([char]0x0000) + if (($regValue -notmatch ".+") -or ([string]::IsNullOrEmpty($regValue)) -or ([string]::IsNullOrWhiteSpace($regValue))) { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '.+'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.6" + Task = "(L2) Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "CachedLogonsCount" ` + | Select-Object -ExpandProperty "CachedLogonsCount" + + if ($regValue -notmatch "^[43210]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[43210]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.7" + Task = "(L1) Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "PasswordExpiryWarning" ` + | Select-Object -ExpandProperty "PasswordExpiryWarning" + + if (($regValue -gt 14 -or $regValue -lt 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 14 and x >= 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.8" + Task = "(L1) Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ForceUnlockLogon" ` + | Select-Object -ExpandProperty "ForceUnlockLogon" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.7.9" + Task = "(L1) Ensure 'Interactive logon: Smart card removal behavior' is set to 1 - 'Lock Workstation' or 2 / 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScRemoveOption" ` + | Select-Object -ExpandProperty "ScRemoveOption" + + if ($regValue -notmatch "^(1|2|3)$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^(1|2|3)$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.8.1" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbClientConfiguration).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.2" + Task = "(L1) Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbClientConfiguration).EnableSecuritySignature -ne $True) { + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.8.3" + Task = "(L1) Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" ` + -Name "EnablePlainTextPassword" ` + | Select-Object -ExpandProperty "EnablePlainTextPassword" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.1" + Task = "(L1) Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "AutoDisconnect" ` + | Select-Object -ExpandProperty "AutoDisconnect" + + if (($regValue -gt 15)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.2" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).RequireSecuritySignature -ne $True) { + return @{ + Message = "RequireSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RequireSecuritySignature" ` + | Select-Object -ExpandProperty "RequireSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.3" + Task = "(L1) Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'" + Test = { + try { + if ((Get-SmbServerConfiguration -ErrorAction Stop).EnableSecuritySignature -ne $True) { + return @{ + Message = "EnableSecuritySignature is not set to True" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } + catch { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "EnableSecuritySignature" ` + | Select-Object -ExpandProperty "EnableSecuritySignature" + + return @{ + Message = "Registry value is '$regValue'. Get-SMBServerConfiguration failed, resorted to checking registry, which might not be 100% accurate. See here and here" + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "2.3.9.4" + Task = "(L1) Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "enableforcedlogoff" ` + | Select-Object -ExpandProperty "enableforcedlogoff" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.9.5" + Task = "(L1) Ensure 'Microsoft network server: Server SPN target name validation level' is set to 1 - 'Accept if provided by client' or 2 - higher (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "SMBServerNameHardeningLevel" ` + | Select-Object -ExpandProperty "SMBServerNameHardeningLevel" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.2" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymousSAM" ` + | Select-Object -ExpandProperty "RestrictAnonymousSAM" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.3" + Task = "(L1) Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RestrictAnonymous" ` + | Select-Object -ExpandProperty "RestrictAnonymous" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.4" + Task = "(L2) Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "DisableDomainCreds" ` + | Select-Object -ExpandProperty "DisableDomainCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.5" + Task = "(L1) Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "EveryoneIncludesAnonymous" ` + | Select-Object -ExpandProperty "EveryoneIncludesAnonymous" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.6" + Task = "(L1) Ensure 'Network access: Named Pipes that can be accessed anonymously' is configured (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + $reference = @( + "LSARPC" + "NETLOGON" + "SAMR" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: LSARPC,NETLOGON,SAMR" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.7" + Task = "(L1) Ensure 'Network access: Named Pipes that can be accessed anonymously' is configured (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionPipes" ` + | Select-Object -ExpandProperty "NullSessionPipes" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.8" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths' is configured" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\ProductOptions" + "System\CurrentControlSet\Control\Server Applications" + "Software\Microsoft\Windows NT\CurrentVersion" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\ProductOptions System\CurrentControlSet\Control\Server Applications Software\Microsoft\Windows NT\CurrentVersion" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +$CARoleStatus = (Get-WindowsFeature -Name ADCS-Cert-Authority).Installed +$WINSStatus = (Get-WindowsFeature -Name WINS).Installed +[AuditTest] @{ + Id = "2.3.10.9 A" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured [WINS Role Feature and CA Role Service NOT installed]" + Test = { + try { + if (($CARoleStatus -or $WINSStatus) -eq $true) { + return @{ + Message = "WINS Role Feature or CA Role Service are installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9 B" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured [CA Role Service installed]" + Test = { + try { + if ($CARoleStatus -eq $false) { + return @{ + Message = "CA Role Service NOT installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + "System\CurrentControlSet\Services\CertSvc" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog System\CurrentControlSet\Services\CertSvc" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.9 C" + Task = "(L1) Ensure 'Network access: Remotely accessible registry paths and sub-paths' is configured [WINS Role Feature installed]" + Test = { + try { + if ($WINSStatus -eq $false) { + return @{ + Message = "WINS Role Feature NOT installed" + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths" ` + -Name "Machine" ` + | Select-Object -ExpandProperty "Machine" + + $reference = @( + "System\CurrentControlSet\Control\Print\Printers" + "System\CurrentControlSet\Services\Eventlog" + "Software\Microsoft\OLAP Server" + "Software\Microsoft\Windows NT\CurrentVersion\Print" + "Software\Microsoft\Windows NT\CurrentVersion\Windows" + "System\CurrentControlSet\Control\ContentIndex" + "System\CurrentControlSet\Control\Terminal Server" + "System\CurrentControlSet\Control\Terminal Server\UserConfig" + "System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" + "Software\Microsoft\Windows NT\CurrentVersion\Perflib" + "System\CurrentControlSet\Services\SysmonLog" + "System\CurrentControlSet\Services\WINS" + ) + if (-not (Test-ArrayEqual $regValue $reference)) { + return @{ + Message = "Registry value is '$regValue'. Expected: System\CurrentControlSet\Control\Print\Printers System\CurrentControlSet\Services\Eventlog Software\Microsoft\OLAP Server Software\Microsoft\Windows NT\CurrentVersion\Print Software\Microsoft\Windows NT\CurrentVersion\Windows System\CurrentControlSet\Control\ContentIndex System\CurrentControlSet\Control\Terminal Server System\CurrentControlSet\Control\Terminal Server\UserConfig System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration Software\Microsoft\Windows NT\CurrentVersion\Perflib System\CurrentControlSet\Services\SysmonLog System\CurrentControlSet\Services\WINS" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.10" + Task = "(L1) Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "RestrictNullSessAccess" ` + | Select-Object -ExpandProperty "RestrictNullSessAccess" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.11" + Task = "(L1) Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "restrictremotesam" ` + | Select-Object -ExpandProperty "restrictremotesam" + + if ($regValue -ne "O:BAG:BAD:(A;;RC;;;BA)") { + return @{ + Message = "Registry value is '$regValue'. Expected: O:BAG:BAD:(A;;RC;;;BA)" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.12" + Task = "(L1) Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters" ` + -Name "NullSessionShares" ` + | Select-Object -ExpandProperty "NullSessionShares" + + if ($regValue -ne "") { + return @{ + Message = "Registry value is '$regValue'. Expected: " + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.13" + Task = "(L1) Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "ForceGuest" ` + | Select-Object -ExpandProperty "ForceGuest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.1" + Task = "(L1) Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "UseMachineId" ` + | Select-Object -ExpandProperty "UseMachineId" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.2" + Task = "(L1) Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AllowNullSessionFallback" ` + | Select-Object -ExpandProperty "AllowNullSessionFallback" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.3" + Task = "(L1) Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\pku2u" ` + -Name "AllowOnlineID" ` + | Select-Object -ExpandProperty "AllowOnlineID" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.4" + Task = "(L1) Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if ($regValue -ne 2147483640) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.5" + Task = "(L1) Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.7" + Task = "(L1) Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "LmCompatibilityLevel" ` + | Select-Object -ExpandProperty "LmCompatibilityLevel" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.8" + Task = "(L1) Ensure 'Network security: LDAP client encryption requirements' is set to 1 - 'Negotiate sealing' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LDAP" ` + -Name "ldapclientconfidentiality" ` + | Select-Object -ExpandProperty "ldapclientconfidentiality" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.9" + Task = "(L1) Ensure 'Network security: LDAP client signing requirements' is set to 1 - 'Negotiate signing' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LDAP" ` + -Name "LDAPClientIntegrity" ` + | Select-Object -ExpandProperty "LDAPClientIntegrity" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.10" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinClientSec" ` + | Select-Object -ExpandProperty "NTLMMinClientSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.11" + Task = "(L1) Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "NTLMMinServerSec" ` + | Select-Object -ExpandProperty "NTLMMinServerSec" + + if ($regValue -ne 537395200) { + return @{ + Message = "Registry value is '$regValue'. Expected: 537395200" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.12" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Audit Incoming NTLM Traffic' is set to 'Enable auditing for all accounts'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "AuditReceivingNTLMTraffic" ` + | Select-Object -ExpandProperty "AuditReceivingNTLMTraffic" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.13" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Audit NTLM authentication in this domain' is set to 'Enable all' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" ` + -Name "AuditNTLMInDomain" ` + | Select-Object -ExpandProperty "AuditNTLMInDomain" + + if ($regValue -ne 7) { + return @{ + Message = "Registry value is '$regValue'. Expected: 7" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.14" + Task = "(L1) Ensure 'Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers' is set to 1 - 'Audit all' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" ` + -Name "RestrictSendingNTLMTraffic" ` + | Select-Object -ExpandProperty "RestrictSendingNTLMTraffic" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.13.1" + Task = "(L1) Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ShutdownWithoutLogon" ` + | Select-Object -ExpandProperty "ShutdownWithoutLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.1" + Task = "(L1) Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel" ` + -Name "ObCaseInsensitive" ` + | Select-Object -ExpandProperty "ObCaseInsensitive" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.15.2" + Task = "(L1) Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "ProtectionMode" ` + | Select-Object -ExpandProperty "ProtectionMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.1" + Task = "(L1) Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "FilterAdministratorToken" ` + | Select-Object -ExpandProperty "FilterAdministratorToken" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.2" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 2 - 'Prompt for consent on the secure desktop' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorAdmin" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorAdmin" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.3" + Task = "(L1) Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "ConsentPromptBehaviorUser" ` + | Select-Object -ExpandProperty "ConsentPromptBehaviorUser" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.4" + Task = "(L1) Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableInstallerDetection" ` + | Select-Object -ExpandProperty "EnableInstallerDetection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.5" + Task = "(L1) Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableSecureUIAPaths" ` + | Select-Object -ExpandProperty "EnableSecureUIAPaths" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.6" + Task = "(L1) Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableLUA" ` + | Select-Object -ExpandProperty "EnableLUA" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.7" + Task = "(L1) Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "PromptOnSecureDesktop" ` + | Select-Object -ExpandProperty "PromptOnSecureDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.17.8" + Task = "(L1) Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableVirtualization" ` + | Select-Object -ExpandProperty "EnableVirtualization" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.1" + Task = "(L1) Ensure 'Print Spooler (Spooler)' is set to 'Disabled' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "5.2" + Task = "(L2) Ensure 'Print Spooler (Spooler)' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.1.1" + Task = "(L1) Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile"; + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile"; + $key = "EnableFirewall"; + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.2" + Task = "(L1) Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.3" + Task = "(L1) Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.4" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\domainfw.log'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\domainfw.log"; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.5" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.6" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.7" + Task = "(L1) Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.1" + Task = "(L1) Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.2" + Task = "(L1) Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.3" + Task = "(L1) Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.4" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\privatefw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\privatefw.log"; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.5" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.6" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.2.7" + Task = "(L1) Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Private" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.1" + Task = "(L1) Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "EnableFirewall" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.2" + Task = "(L1) Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DefaultInboundAction" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.3" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "DisableNotifications" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.4" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.5" + Task = "(L1) Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" + $key = "AllowLocalIPsecPolicyMerge" + $expectedValue = 0; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.6" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SystemRoot%\System32\logfiles\firewall\publicfw.log'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFilePath" + $expectedValue = "%SystemRoot%\System32\logfiles\firewall\publicfw.log"; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.7" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogFileSize" + $expectedValue = 16384; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.8" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.9" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'" + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Public" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.3.9" + Task = "(L1) Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging" ` + -Name "LogSuccessfulConnections" ` + | Select-Object -ExpandProperty "LogSuccessfulConnections" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.1.1" + Task = "(L1) Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenCamera" ` + | Select-Object -ExpandProperty "NoLockScreenCamera" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.1.2" + Task = "(L1) Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization" ` + -Name "NoLockScreenSlideshow" ` + | Select-Object -ExpandProperty "NoLockScreenSlideshow" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.2.2" + Task = "(L1) Ensure 'Allow users to enable online speech recognition services' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization" ` + -Name "AllowInputPersonalization" ` + | Select-Object -ExpandProperty "AllowInputPersonalization" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.1.3" + Task = "(L2) Ensure 'Allow Online Tips' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "AllowOnlineTips" ` + | Select-Object -ExpandProperty "AllowOnlineTips" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.1" + Task = "(L1) Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "LocalAccountTokenFilterPolicy" ` + | Select-Object -ExpandProperty "LocalAccountTokenFilterPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.2" + Task = "(L1) Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.3" + Task = "(L1) Ensure 'Configure SMB v1 server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.4" + Task = "(L1) Ensure 'Enable Certificate Padding' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Wintrust\Config" ` + -Name "EnableCertPaddingCheck" ` + | Select-Object -ExpandProperty "EnableCertPaddingCheck" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.5" + Task = "(L1) Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel" ` + -Name "DisableExceptionChainValidation" ` + | Select-Object -ExpandProperty "DisableExceptionChainValidation" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.6" + Task = "(L1) Ensure 'NetBT NodeType configuration' is set to 'Enabled: P-node (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "NodeType" ` + | Select-Object -ExpandProperty "NodeType" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.4.7" + Task = "(L1) Ensure 'WDigest Authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.1" + Task = "(L1) Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "AutoAdminLogon" ` + | Select-Object -ExpandProperty "AutoAdminLogon" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.2" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.3" + Task = "(L1) Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level' is set to 'Enabled: Highest protection, source routing is completely disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "DisableIPSourceRouting" ` + | Select-Object -ExpandProperty "DisableIPSourceRouting" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.4" + Task = "(L1) Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "EnableICMPRedirect" ` + | Select-Object -ExpandProperty "EnableICMPRedirect" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.5" + Task = "(L2) Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "KeepAliveTime" ` + | Select-Object -ExpandProperty "KeepAliveTime" + + if ($regValue -ne 300000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 300000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.6" + Task = "(L1) Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters" ` + -Name "nonamereleaseondemand" ` + | Select-Object -ExpandProperty "nonamereleaseondemand" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.7" + Task = "(L2) Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "PerformRouterDiscovery" ` + | Select-Object -ExpandProperty "PerformRouterDiscovery" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.8" + Task = "(L1) Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager" ` + -Name "SafeDllSearchMode" ` + | Select-Object -ExpandProperty "SafeDllSearchMode" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.9" + Task = "(L1) Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "ScreenSaverGracePeriod" ` + | Select-Object -ExpandProperty "ScreenSaverGracePeriod" + + if ($regValue -notmatch "^[0-5]$") { + return @{ + Message = "Registry value is '$regValue'. Expected: Matching expression '^[0-5]$'" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.10" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.11" + Task = "(L2) Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" ` + -Name "tcpmaxdataretransmissions" ` + | Select-Object -ExpandProperty "tcpmaxdataretransmissions" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.5.12" + Task = "(L1) Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security" ` + -Name "WarningLevel" ` + | Select-Object -ExpandProperty "WarningLevel" + + if (($regValue -gt 90)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 90" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.1" + Task = "(L1) Ensure 'Configure multicast DNS (mDNS) protocol' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMDNS" ` + | Select-Object -ExpandProperty "EnableMDNS" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.2" + Task = "(L1) Ensure 'Configure NetBIOS settings' is set to 2 - 'Enabled: Disable NetBIOS name resolution on public networks' or 0 - 'Enabled: Disable NetBIOS name resolution'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableNetBIOS" ` + | Select-Object -ExpandProperty "EnableNetBIOS" + + if (($regValue -ne 2) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2 or 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.3" + Task = "(L2) Ensure 'Turn off default IPv6 DNS Servers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "DisableIPv6DefaultDnsServers" ` + | Select-Object -ExpandProperty "DisableIPv6DefaultDnsServers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.4.4" + Task = "(L1) Ensure 'Turn off multicast name resolution' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" ` + -Name "EnableMulticast" ` + | Select-Object -ExpandProperty "EnableMulticast" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.5.1" + Task = "(L2) Ensure 'Enable Font Providers' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableFontProviders" ` + | Select-Object -ExpandProperty "EnableFontProviders" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.1" + Task = "(L1) Ensure 'Audit client does not support encryption' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanServer" ` + -Name "AuditClientDoesNotSupportEncryption" ` + | Select-Object -ExpandProperty "AuditClientDoesNotSupportEncryption" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.2" + Task = "(L1) Ensure 'Audit client does not support signing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanServer" ` + -Name "AuditClientDoesNotSupportSigning" ` + | Select-Object -ExpandProperty "AuditClientDoesNotSupportSigning" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.3" + Task = "(L1) Ensure 'Audit insecure guest logon' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanServer" ` + -Name "AuditInsecureGuestLogon" ` + | Select-Object -ExpandProperty "AuditInsecureGuestLogon" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.4" + Task = "(L1) Ensure 'Enable remote mailslots' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Bowser" ` + -Name "EnableMailslots" ` + | Select-Object -ExpandProperty "EnableMailslots" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.5" + Task = "(L1) Ensure 'Mandate the minimum version of SMB' is set to 'Enabled: 3.1.1'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanServer" ` + -Name "MinSmb2Dialect" ` + | Select-Object -ExpandProperty "MinSmb2Dialect" + + if ($regValue -ne 785) { + return @{ + Message = "Registry value is '$regValue'. Expected: 785" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.7.6" + Task = "(L1) Ensure 'Set authentication rate limiter delay (milliseconds)' is set to 'Enabled: 2000' or more" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanServer" ` + -Name "InvalidAuthenticationDelayTimeInMs" ` + | Select-Object -ExpandProperty "InvalidAuthenticationDelayTimeInMs" + + if (($regValue -lt 2000)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 2000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.1" + Task = "(L1) Ensure 'Audit insecure guest logon' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AuditInsecureGuestLogon" ` + | Select-Object -ExpandProperty "AuditInsecureGuestLogon" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.2" + Task = "(L1) Ensure 'Audit server does not support encryption' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AuditServerDoesNotSupportEncryption" ` + | Select-Object -ExpandProperty "AuditServerDoesNotSupportEncryption" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.3" + Task = "(L1) Ensure 'Audit server does not support signing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AuditServerDoesNotSupportSigning" ` + | Select-Object -ExpandProperty "AuditServerDoesNotSupportSigning" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.4" + Task = "(L1) Ensure 'Enable authentication rate limiter' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanServer" ` + -Name "EnableAuthRateLimiter" ` + | Select-Object -ExpandProperty "EnableAuthRateLimiter" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.5" + Task = "(L1) Ensure 'Enable insecure guest logons' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "AllowInsecureGuestAuth" ` + | Select-Object -ExpandProperty "AllowInsecureGuestAuth" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.6" + Task = "(L1) Ensure 'Enable remote mailslots' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider" ` + -Name "EnableMailslots" ` + | Select-Object -ExpandProperty "EnableMailslots" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.7" + Task = "(L1) Ensure 'Mandate the minimum version of SMB' is set to 'Enabled: 3.1.1'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "MinSmb2Dialect" ` + | Select-Object -ExpandProperty "MinSmb2Dialect" + + if ($regValue -ne 785) { + return @{ + Message = "Registry value is '$regValue'. Expected: 785" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.8.8" + Task = "(L1) Ensure 'Require Encryption' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation" ` + -Name "RequireEncryption" ` + | Select-Object -ExpandProperty "RequireEncryption" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 A" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnDomain" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 B" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowLLTDIOOnPublicNet" ` + | Select-Object -ExpandProperty "AllowLLTDIOOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 C" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (EnableLLTDIO)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableLLTDIO" ` + | Select-Object -ExpandProperty "EnableLLTDIO" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.1 D" + Task = "(L2) Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitLLTDIOOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitLLTDIOOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 A" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Domain network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnDomain" ` + | Select-Object -ExpandProperty "AllowRspndrOnDomain" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 B" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Public network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "AllowRspndrOnPublicNet" ` + | Select-Object -ExpandProperty "AllowRspndrOnPublicNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 C" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (EnableRspndr)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "EnableRspndr" ` + | Select-Object -ExpandProperty "EnableRspndr" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.9.2 D" + Task = "(L2) Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' (Private network)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD" ` + -Name "ProhibitRspndrOnPrivateNet" ` + | Select-Object -ExpandProperty "ProhibitRspndrOnPrivateNet" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.10.2" + Task = "(L2) Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.2" + Task = "(L1) Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_AllowNetBridge_NLA" ` + | Select-Object -ExpandProperty "NC_AllowNetBridge_NLA" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.3" + Task = "(L1) Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_ShowSharedAccessUI" ` + | Select-Object -ExpandProperty "NC_ShowSharedAccessUI" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.11.4" + Task = "(L1) Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections" ` + -Name "NC_StdDomainUserSetLocation" ` + | Select-Object -ExpandProperty "NC_StdDomainUserSetLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 A" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares' (\\*\NETLOGON)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\NETLOGON" ` + | Select-Object -ExpandProperty "\\*\NETLOGON" + + if ($regValue -eq $null) { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object { $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "RequirePrivacy=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.14.1 B" + Task = "(L1) Ensure 'Hardened UNC Paths' is set to 'Enabled, with `"Require Mutual Authentication`", `"Require Integrity`", and `"Require Privacy`" set for all NETLOGON and SYSVOL shares' (\\*\SYSVOL)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths" ` + -Name "\\*\SYSVOL" ` + | Select-Object -ExpandProperty "\\*\SYSVOL" + + if ($regValue -eq $null) { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + $array = $regValue.Split(',') | ForEach-Object { $_.Trim() } + + $missingElements = @() + $elementsToCheck = @("RequireMutualAuthentication=1", "RequireIntegrity=1", "RequirePrivacy=1") + foreach ($element in $elementsToCheck) { + if ($array -notcontains $element) { + $missingElements += $element + } + } + + if ($missingElements.Length -gt 0) { + return @{ + Message = ($missingElements -join " and ") + " not configured correctly." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.19.2.1" + Task = "(L2) Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" ` + -Name "DisabledComponents" ` + | Select-Object -ExpandProperty "DisabledComponents" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 A" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (EnableRegistrars)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "EnableRegistrars" ` + | Select-Object -ExpandProperty "EnableRegistrars" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 B" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableUPnPRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableUPnPRegistrar" ` + | Select-Object -ExpandProperty "DisableUPnPRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 C" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableInBand802DOT11Registrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableInBand802DOT11Registrar" ` + | Select-Object -ExpandProperty "DisableInBand802DOT11Registrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 D" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableFlashConfigRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableFlashConfigRegistrar" ` + | Select-Object -ExpandProperty "DisableFlashConfigRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.1 E" + Task = "(L2) Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' (DisableWPDRegistrar)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" ` + -Name "DisableWPDRegistrar" ` + | Select-Object -ExpandProperty "DisableWPDRegistrar" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.20.2" + Task = "(L2) Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI" ` + -Name "DisableWcnUi" ` + | Select-Object -ExpandProperty "DisableWcnUi" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.1" + Task = "(L1) Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled: 3 = Prevent Wi-Fi when on Ethernet'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fMinimizeConnections" ` + | Select-Object -ExpandProperty "fMinimizeConnections" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.21.2" + Task = "(L2) Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy" ` + -Name "fBlockNonDomain" ` + | Select-Object -ExpandProperty "fBlockNonDomain" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.1" + Task = "(L1) Ensure 'Allow Print Spooler to accept client connections' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "RegisterSpoolerRemoteRpcEndPoint" ` + | Select-Object -ExpandProperty "RegisterSpoolerRemoteRpcEndPoint" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.2" + Task = "(L1) Ensure 'Configure Redirection Guard' is set to 'Enabled: Redirection Guard Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "RedirectionGuardPolicy" ` + | Select-Object -ExpandProperty "RedirectionGuardPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.3" + Task = "(L1) Ensure 'Configure RPC connection settings: Protocol to use for outgoing RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcUseNamedPipeProtocol" ` + | Select-Object -ExpandProperty "RpcUseNamedPipeProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.4" + Task = "(L1) Ensure 'Configure RPC connection settings: Use authentication for outgoing RPC connections' is set to 'Enabled: Default'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcAuthentication" ` + | Select-Object -ExpandProperty "RpcAuthentication" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.5" + Task = "(L1) Ensure 'Configure RPC listener settings: Protocols to allow for incoming RPC connections' is set to 'Enabled: RPC over TCP'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcProtocols" ` + | Select-Object -ExpandProperty "RpcProtocols" + + if ($regValue -ne 5) { + return @{ + Message = "Registry value is '$regValue'. Expected: 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.6" + Task = "(L1) Ensure 'Configure RPC listener settings: Authentication protocol to use for incoming RPC connections:' is set to 'Enabled: 0 - Negotiate' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "ForceKerberosForRpc" ` + | Select-Object -ExpandProperty "ForceKerberosForRpc" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0 or 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.7" + Task = "(L1) Ensure 'Configure RPC over TCP port' is set to 'Enabled: 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\RPC" ` + -Name "RpcTcpPort" ` + | Select-Object -ExpandProperty "RpcTcpPort" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.8" + Task = "(L1) Ensure 'Configure RPC packet level privacy setting for incoming connections' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print" ` + -Name "RpcAuthnLevelPrivacyEnabled" ` + | Select-Object -ExpandProperty "RpcAuthnLevelPrivacyEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.9" + Task = "(L2) Ensure 'Configure Windows protected print' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\WPP" ` + -Name "WindowsProtectedPrintGroupPolicyState" ` + | Select-Object -ExpandProperty "WindowsProtectedPrintGroupPolicyState" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.10" + Task = "(L1) Ensure 'Limits print driver installation to Administrators' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "RestrictDriverInstallationToAdministrators" ` + | Select-Object -ExpandProperty "RestrictDriverInstallationToAdministrators" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.11" + Task = "(L1) Ensure 'Manage processing of Queue-specific files' is set to 'Enabled: Limit Queue-specific files to Color profiles'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "CopyFilesPolicy" ` + | Select-Object -ExpandProperty "CopyFilesPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.12" + Task = "(L1) Ensure 'Point and Print Restrictions: When installing drivers for a new connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "NoWarningNoElevationOnInstall" ` + | Select-Object -ExpandProperty "NoWarningNoElevationOnInstall" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.7.13" + Task = "(L1) Ensure 'Point and Print Restrictions: When updating drivers for an existing connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "UpdatePromptSettings" ` + | Select-Object -ExpandProperty "UpdatePromptSettings" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.8.1.1" + Task = "(L2) Ensure 'Turn off notifications network usage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoCloudApplicationNotification" ` + | Select-Object -ExpandProperty "NoCloudApplicationNotification" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.3.1" + Task = "(L1) Ensure 'Include command line in process creation events' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ` + -Name "ProcessCreationIncludeCmdLine_Enabled" ` + | Select-Object -ExpandProperty "ProcessCreationIncludeCmdLine_Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.1" + Task = "(L1) Ensure 'Encryption Oracle Remediation' is set to 'Enabled: Force Updated Clients'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters" ` + -Name "AllowEncryptionOracle" ` + | Select-Object -ExpandProperty "AllowEncryptionOracle" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.4.2" + Task = "(L1) Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation" ` + -Name "AllowProtectedCreds" ` + | Select-Object -ExpandProperty "AllowProtectedCreds" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.1" + Task = "(NG) Ensure 'Turn On Virtualization Based Security' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "EnableVirtualizationBasedSecurity" ` + | Select-Object -ExpandProperty "EnableVirtualizationBasedSecurity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.2" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Select Platform Security Level' is set to 1 - 'Secure Boot' or 3 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "RequirePlatformSecurityFeatures" ` + | Select-Object -ExpandProperty "RequirePlatformSecurityFeatures" + + if (($regValue -ne 1) -and ($regValue -ne 3)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.3" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Virtualization Based Protection of Code Integrity' is set to 'Enabled with UEFI lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HypervisorEnforcedCodeIntegrity" ` + | Select-Object -ExpandProperty "HypervisorEnforcedCodeIntegrity" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.4" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Require UEFI Memory Attributes Table' is set to 'True (checked)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "HVCIMATRequired" ` + | Select-Object -ExpandProperty "HVCIMATRequired" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.5" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Enabled with UEFI lock' (MS Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.6" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Credential Guard Configuration' is set to 'Disabled' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "LsaCfgFlags" ` + | Select-Object -ExpandProperty "LsaCfgFlags" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.5.7" + Task = "(NG) Ensure 'Turn On Virtualization Based Security: Secure Launch Configuration' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard" ` + -Name "ConfigureSystemGuardLaunch" ` + | Select-Object -ExpandProperty "ConfigureSystemGuardLaunch" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.7.2" + Task = "(L1) Ensure 'Prevent device metadata retrieval from the Internet' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" ` + -Name "PreventDeviceMetadataFromNetwork" ` + | Select-Object -ExpandProperty "PreventDeviceMetadataFromNetwork" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.13.1" + Task = "(L1) Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch" ` + -Name "DriverLoadPolicy" ` + | Select-Object -ExpandProperty "DriverLoadPolicy" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.2" + Task = "(L1) Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.3" + Task = "(L1) Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.4" + Task = "(L1) Ensure 'Configure security policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoBackgroundPolicy" ` + | Select-Object -ExpandProperty "NoBackgroundPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.5" + Task = "(L1) Ensure 'Configure security policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" ` + -Name "NoGPOListChanges" ` + | Select-Object -ExpandProperty "NoGPOListChanges" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.6" + Task = "(L1) Ensure 'Continue experiences on this device' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableCdp" ` + | Select-Object -ExpandProperty "EnableCdp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.19.7" + Task = "(L1) Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableBkGndGroupPolicy" ` + | Select-Object -ExpandProperty "DisableBkGndGroupPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.1" + Task = "(L1) Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableWebPnPDownload" ` + | Select-Object -ExpandProperty "DisableWebPnPDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.2" + Task = "(L2) Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC" ` + -Name "PreventHandwritingDataSharing" ` + | Select-Object -ExpandProperty "PreventHandwritingDataSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.3" + Task = "(L2) Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports" ` + -Name "PreventHandwritingErrorReports" ` + | Select-Object -ExpandProperty "PreventHandwritingErrorReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.4" + Task = "(L2) Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard" ` + -Name "ExitOnMSICW" ` + | Select-Object -ExpandProperty "ExitOnMSICW" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.5" + Task = "(L1) Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoWebServices" ` + | Select-Object -ExpandProperty "NoWebServices" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.6" + Task = "(L2) Ensure 'Turn off printing over HTTP' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers" ` + -Name "DisableHTTPPrinting" ` + | Select-Object -ExpandProperty "DisableHTTPPrinting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.7" + Task = "(L2) Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Registration Wizard Control" ` + -Name "NoRegistration" ` + | Select-Object -ExpandProperty "NoRegistration" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.8" + Task = "(L2) Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion" ` + -Name "DisableContentFileUpdates" ` + | Select-Object -ExpandProperty "DisableContentFileUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.9" + Task = "(L2) Ensure 'Turn off the `"Order Prints`" picture task' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoOnlinePrintsWizard" ` + | Select-Object -ExpandProperty "NoOnlinePrintsWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.10" + Task = "(L2) Ensure 'Turn off the `"Publish to Web`" task for files and folders' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoPublishingWizard" ` + | Select-Object -ExpandProperty "NoPublishingWizard" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.11" + Task = "(L2) Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client" ` + -Name "CEIP" ` + | Select-Object -ExpandProperty "CEIP" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.12" + Task = "(L2) Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows" ` + -Name "CEIPEnable" ` + | Select-Object -ExpandProperty "CEIPEnable" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13 A" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (Disabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" ` + -Name "Disabled" ` + | Select-Object -ExpandProperty "Disabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.20.1.13 B" + Task = "(L2) Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' (DoReport)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting" ` + -Name "DoReport" ` + | Select-Object -ExpandProperty "DoReport" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 A" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitBehavior)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitBehavior" ` + | Select-Object -ExpandProperty "DevicePKInitBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.23.1 B" + Task = "(L2) Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' (DevicePKInitEnabled)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters" ` + -Name "DevicePKInitEnabled" ` + | Select-Object -ExpandProperty "DevicePKInitEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.24.1" + Task = "(L1) Ensure 'Enumeration policy for external devices incompatible with Kernel DMA Protection' is set to 'Enabled: Block All'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Kernel DMA Protection" ` + -Name "DeviceEnumerationPolicy" ` + | Select-Object -ExpandProperty "DeviceEnumerationPolicy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.1" + Task = "(L1) Ensure 'Configure password backup directory' is set to 2 - 'Enabled: Active Directory' or 1 - 'Enabled: Azure Active Directory'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "BackupDirectory" ` + | Select-Object -ExpandProperty "BackupDirectory" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.2" + Task = "(L1) Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PwdExpirationProtectionEnabled" ` + | Select-Object -ExpandProperty "PwdExpirationProtectionEnabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.3" + Task = "(L1) Ensure 'Enable password encryption' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "ADPasswordEncryptionEnabled" ` + | Select-Object -ExpandProperty "ADPasswordEncryptionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.4" + Task = "(L1) Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordComplexity" ` + | Select-Object -ExpandProperty "PasswordComplexity" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.5" + Task = "(L1) Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordLength" ` + | Select-Object -ExpandProperty "PasswordLength" + + if ($regValue -lt 15) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 15" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.6" + Task = "(L1) Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PasswordAgeDays" ` + | Select-Object -ExpandProperty "PasswordAgeDays" + + if ($regValue -gt 30 -or $regValue -lt 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 30 and x >= 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.7" + Task = "(L1) Ensure 'Post-authentication actions: Grace period (hours)' is set to 'Enabled: 8 or fewer hours, but not 0'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PostAuthenticationResetDelay" ` + | Select-Object -ExpandProperty "PostAuthenticationResetDelay" + + if (($regValue -gt 8 -or $regValue -le 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 8 and x > 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.25.8" + Task = "(L1) Ensure 'Post-authentication actions: Actions' is set to 3 - 'Enabled: Reset the password and logoff the managed account' or 5 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\LAPS" ` + -Name "PostAuthenticationActions" ` + | Select-Object -ExpandProperty "PostAuthenticationActions" + + if (($regValue -ne 3) -and ($regValue -ne 5)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3 or 5" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.1" + Task = "(L1) Ensure 'Allow Custom SSPs and APs to be loaded into LSASS' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowCustomSSPsAPs" ` + | Select-Object -ExpandProperty "AllowCustomSSPsAPs" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.26.2" + Task = "(NG) Ensure 'Configures LSASS to run as a protected process' is set to 'Enabled: Enabled with UEFI Lock'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" ` + -Name "RunAsPPL" ` + | Select-Object -ExpandProperty "RunAsPPL" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.27.1" + Task = "(L2) Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International" ` + -Name "BlockUserInputMethodsForSignIn" ` + | Select-Object -ExpandProperty "BlockUserInputMethodsForSignIn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.1" + Task = "(L1) Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockUserFromShowingAccountDetailsOnSignin" ` + | Select-Object -ExpandProperty "BlockUserFromShowingAccountDetailsOnSignin" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.2" + Task = "(L1) Ensure 'Do not display network selection UI' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DontDisplayNetworkSelectionUI" ` + | Select-Object -ExpandProperty "DontDisplayNetworkSelectionUI" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.3" + Task = "(L1) Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DontEnumerateConnectedUsers" ` + | Select-Object -ExpandProperty "DontEnumerateConnectedUsers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.4" + Task = "(L1) Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnumerateLocalUsers" ` + | Select-Object -ExpandProperty "EnumerateLocalUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.5" + Task = "(L1) Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "DisableLockScreenAppNotifications" ` + | Select-Object -ExpandProperty "DisableLockScreenAppNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.6" + Task = "(L1) Ensure 'Turn off picture password sign-in' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "BlockDomainPicturePassword" ` + | Select-Object -ExpandProperty "BlockDomainPicturePassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.28.7" + Task = "(L1) Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowDomainPINLogon" ` + | Select-Object -ExpandProperty "AllowDomainPINLogon" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.30.1.1" + Task = "(L1) Ensure 'Block NetBIOS-based discovery for domain controller location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Netlogon\Parameters" ` + -Name "BlockNetbiosDiscovery" ` + | Select-Object -ExpandProperty "BlockNetbiosDiscovery" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.31.1" + Task = "(L2) Ensure 'Allow Clipboard synchronization across devices' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "AllowCrossDeviceClipboard" ` + | Select-Object -ExpandProperty "AllowCrossDeviceClipboard" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.31.2" + Task = "(L2) Ensure 'Allow upload of User Activities' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "UploadUserActivities" ` + | Select-Object -ExpandProperty "UploadUserActivities" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.1" + Task = "(L2) Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.2" + Task = "(L2) Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.3" + Task = "(L1) Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "DCSettingIndex" ` + | Select-Object -ExpandProperty "DCSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.33.6.4" + Task = "(L1) Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51" ` + -Name "ACSettingIndex" ` + | Select-Object -ExpandProperty "ACSettingIndex" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.1" + Task = "(L1) Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowUnsolicited" ` + | Select-Object -ExpandProperty "fAllowUnsolicited" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.35.2" + Task = "(L1) Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fAllowToGetHelp" ` + | Select-Object -ExpandProperty "fAllowToGetHelp" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.36.1" + Task = "(L1) Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" ` + -Name "EnableAuthEpResolution" ` + | Select-Object -ExpandProperty "EnableAuthEpResolution" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.36.2" + Task = "(L2) Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc" ` + -Name "RestrictRemoteClients" ` + | Select-Object -ExpandProperty "RestrictRemoteClients" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.39.1" + Task = "(L1) Ensure 'Configure validation of ROCA-vulnerable WHfB keys during authentication' is set to 1 - 'Enabled: Audit' or 2 - higher (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\SAM" ` + -Name "SamNGCKeyROCAValidation" ` + | Select-Object -ExpandProperty "SamNGCKeyROCAValidation" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.39.2" + Task = "(L1) Ensure 'Configure SAM change password RPC methods policy' is set to 'Enabled: Allow strong encryption change password RPC method only' (DC only)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\SAM" ` + -Name "SamrChangeUserPasswordApiPolicy" ` + | Select-Object -ExpandProperty "SamrChangeUserPasswordApiPolicy" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.39.3" + Task = "(L1) Ensure 'Configure SAM change password RPC methods policy' is set to 'Enabled: Block all change password RPC methods' (MS only)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\SAM" ` + -Name "SamrChangeUserPasswordApiPolicy" ` + | Select-Object -ExpandProperty "SamrChangeUserPasswordApiPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1" + Task = "(L2) Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy" ` + -Name "DisableQueryRemoteServer" ` + | Select-Object -ExpandProperty "DisableQueryRemoteServer" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.11.1" + Task = "(L2) Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d}" ` + -Name "ScenarioExecutionEnabled" ` + | Select-Object -ExpandProperty "ScenarioExecutionEnabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.49.1" + Task = "(L2) Ensure 'Turn off the advertising ID' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" ` + -Name "DisabledByGroupPolicy" ` + | Select-Object -ExpandProperty "DisabledByGroupPolicy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.51.1.1" + Task = "(L1) Ensure 'Enable Windows NTP Client' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.51.1.2" + Task = "(L1) Ensure 'Enable Windows NTP Server' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.4.1" + Task = "(L2) Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager" ` + -Name "AllowSharedLocalAppData" ` + | Select-Object -ExpandProperty "AllowSharedLocalAppData" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.4.2" + Task = "(L1) Ensure 'Not allow per-user unsigned packages to install by default (requires explicitly allow per install)' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Appx" ` + -Name "DisablePerUserUnsignedPackagesByDefault" ` + | Select-Object -ExpandProperty "DisablePerUserUnsignedPackagesByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.6.1" + Task = "(L1) Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "MSAOptional" ` + | Select-Object -ExpandProperty "MSAOptional" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.8.1" + Task = "(L1) Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoAutoplayfornonVolume" ` + | Select-Object -ExpandProperty "NoAutoplayfornonVolume" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.8.2" + Task = "(L1) Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoAutorun" ` + | Select-Object -ExpandProperty "NoAutorun" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.8.3" + Task = "(L1) Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoDriveTypeAutoRun" ` + | Select-Object -ExpandProperty "NoDriveTypeAutoRun" + + if ($regValue -ne 255) { + return @{ + Message = "Registry value is '$regValue'. Expected: 255" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.9.1.1" + Task = "(L1) Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures" ` + -Name "EnhancedAntiSpoofing" ` + | Select-Object -ExpandProperty "EnhancedAntiSpoofing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.11.1" + Task = "(L2) Ensure 'Allow Use of Camera' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera" ` + -Name "AllowCamera" ` + | Select-Object -ExpandProperty "AllowCamera" + + if ($regValue -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam" ` + -Name "Value" ` + | Select-Object -ExpandProperty "Value" + + if ($regValue -match "Deny") { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Camera is not deactivated." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "18.10.13.1" + Task = "(L1) Ensure 'Turn off cloud consumer account state content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableConsumerAccountStateContent" ` + | Select-Object -ExpandProperty "DisableConsumerAccountStateContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.13.2" + Task = "(L2) Ensure 'Turn off cloud optimized content' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableCloudOptimizedContent" ` + | Select-Object -ExpandProperty "DisableCloudOptimizedContent" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.13.3" + Task = "(L1) Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsConsumerFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsConsumerFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.14.1" + Task = "(L1) Ensure 'Require pin for pairing' is set to 'Enabled: First Time' OR 'Enabled: Always'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect" ` + -Name "RequirePinForPairing" ` + | Select-Object -ExpandProperty "RequirePinForPairing" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or x 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.1" + Task = "(L1) Ensure 'Do not display the password reveal button' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI" ` + -Name "DisablePasswordReveal" ` + | Select-Object -ExpandProperty "DisablePasswordReveal" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.15.2" + Task = "(L1) Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI" ` + -Name "EnumerateAdministrators" ` + | Select-Object -ExpandProperty "EnumerateAdministrators" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.1" + Task = "(L1) Ensure 'Allow Diagnostic Data' is set to '0 - Enabled: Diagnostic data off (not recommended)' or '1 - Enabled: Send required diagnostic data'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "AllowTelemetry" ` + | Select-Object -ExpandProperty "AllowTelemetry" + + if (($regValue -ne 0) -and ($regValue -ne 1)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0 or x 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.2" + Task = "(L2) Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableEnterpriseAuthProxy" ` + | Select-Object -ExpandProperty "DisableEnterpriseAuthProxy" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.3" + Task = "(L1) Ensure 'Disable OneSettings Downloads' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DisableOneSettingsDownloads" ` + | Select-Object -ExpandProperty "DisableOneSettingsDownloads" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.4" + Task = "(L1) Ensure 'Do not show feedback notifications' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "DoNotShowFeedbackNotifications" ` + | Select-Object -ExpandProperty "DoNotShowFeedbackNotifications" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.5" + Task = "(L1) Ensure 'Enable OneSettings Auditing' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "EnableOneSettingsAuditing" ` + | Select-Object -ExpandProperty "EnableOneSettingsAuditing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.6" + Task = "(L1) Ensure 'Limit Diagnostic Log Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDiagnosticLogCollection" ` + | Select-Object -ExpandProperty "LimitDiagnosticLogCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.7" + Task = "(L1) Ensure 'Limit Dump Collection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" ` + -Name "LimitDumpCollection" ` + | Select-Object -ExpandProperty "LimitDumpCollection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.16.8" + Task = "(L1) Ensure 'Toggle user control over Insider builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" ` + -Name "AllowBuildPreview" ` + | Select-Object -ExpandProperty "AllowBuildPreview" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.1" + Task = "(L2) Ensure 'Enable App Installer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableAppInstaller" ` + | Select-Object -ExpandProperty "EnableAppInstaller" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.2" + Task = "(L1) Ensure 'Enable App Installer Experimental Features' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableExperimentalFeatures" ` + | Select-Object -ExpandProperty "EnableExperimentalFeatures" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.3" + Task = "(L1) Ensure 'Enable App Installer Hash Override' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableHashOverride" ` + | Select-Object -ExpandProperty "EnableHashOverride" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.4" + Task = "(L1) Ensure 'Enable App Installer Local Archive Malware Scan Override' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableLocalArchiveMalwareScanOverride" ` + | Select-Object -ExpandProperty "EnableLocalArchiveMalwareScanOverride" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.5" + Task = "(L1) Ensure 'Enable App Installer ms-appinstaller protocol' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableMSAppInstallerProtocol" ` + | Select-Object -ExpandProperty "EnableMSAppInstallerProtocol" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.6" + Task = "(L1) Ensure 'Enable App Installer Microsoft Store Source Certificate Validation Bypass' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableBypassCertificatePinningForMicrosoftStore" ` + | Select-Object -ExpandProperty "EnableBypassCertificatePinningForMicrosoftStore" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.18.7" + Task = "(L2) Ensure 'Enable Windows Package Manager command line interfaces' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppInstaller" ` + -Name "EnableWindowsPackageManagerCommandLineInterfaces" ` + | Select-Object -ExpandProperty "EnableWindowsPackageManagerCommandLineInterfaces" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.1.1" + Task = "(L1) Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.1.2" + Task = "(L1) Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.2.1" + Task = "(L1) Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.2.2" + Task = "(L1) Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 196608)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 196608" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.3.1" + Task = "(L1) Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.3.2" + Task = "(L1) Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.4.1" + Task = "(L1) Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" ` + -Name "Retention" ` + | Select-Object -ExpandProperty "Retention" + + if ($regValue -ne "0") { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.26.4.2" + Task = "(L1) Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System" ` + -Name "MaxSize" ` + | Select-Object -ExpandProperty "MaxSize" + + if (($regValue -lt 32768)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 32768" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.2" + Task = "(L1) Ensure 'Do not apply the Mark of the Web tag to files copied from insecure sources' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "DisableMotWOnInsecurePathCopy" ` + | Select-Object -ExpandProperty "DisableMotWOnInsecurePathCopy" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.3" + Task = "(L1) Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoDataExecutionPrevention" ` + | Select-Object -ExpandProperty "NoDataExecutionPrevention" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.4" + Task = "(L1) Ensure 'Turn off heap termination on corruption' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer" ` + -Name "NoHeapTerminationOnCorruption" ` + | Select-Object -ExpandProperty "NoHeapTerminationOnCorruption" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.29.5" + Task = "(L1) Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "PreXPSP2ShellProtocolBehavior" ` + | Select-Object -ExpandProperty "PreXPSP2ShellProtocolBehavior" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.37.1" + Task = "(L2) Ensure 'Turn off location' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors" ` + -Name "DisableLocation" ` + | Select-Object -ExpandProperty "DisableLocation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.41.1" + Task = "(L2) Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging" ` + -Name "AllowMessageSync" ` + | Select-Object -ExpandProperty "AllowMessageSync" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.42.1" + Task = "(L1) Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount" ` + -Name "DisableUserAuth" ` + | Select-Object -ExpandProperty "DisableUserAuth" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.4.1" + Task = "(L1) Ensure 'Enable EDR in block mode' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Features" ` + -Name "PassiveRemediation" ` + | Select-Object -ExpandProperty "PassiveRemediation" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.5.1" + Task = "(L1) Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "LocalSettingOverrideSpynetReporting" ` + | Select-Object -ExpandProperty "LocalSettingOverrideSpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.5.2" + Task = "(L2) Ensure 'Join Microsoft MAPS' is set to 'Disabled'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" ` + -Name "SpynetReporting" ` + | Select-Object -ExpandProperty "SpynetReporting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.1" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value = "ExploitGuard_ASR_Rules" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + $Value2 = "ExploitGuard_ASR_Rules" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 A" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office communication application from creating child processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 B" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating executable content'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 C" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block abuse of exploited vulnerable signed drivers'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 D" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block execution of potentially obfuscated scripts'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 E" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from injecting code into other processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 F" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Adobe Reader from creating child processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 H" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block untrusted and unsigned processes that run from USB'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 J" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block JavaScript or VBScript from launching downloaded executable content'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 K" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block Office applications from creating child processes'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 I" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block executable content from email client and webmail'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 L" + Task = "(L1) Ensure 'Configure Attack Surface Reduction rules: Block persistence through WMI event subscription'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.3.1" + Task = "(L1) Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'" + Test = { + try { + if (-not $windefrunning) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection" ` + -Name "EnableNetworkProtection" ` + | Select-Object -ExpandProperty "EnableNetworkProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.7.1" + Task = "(L1) Ensure 'Enable file hash computation feature' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\NIS" ` + -Name "EnableConvertWarnToBlock" ` + | Select-Object -ExpandProperty "EnableConvertWarnToBlock" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.1" + Task = "(L1) Ensure 'Configure real-time protection and Security Intelligence Updates during OOBE' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "OobeEnableRtpAndSigUpdate" ` + | Select-Object -ExpandProperty "OobeEnableRtpAndSigUpdate" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.2" + Task = "(L1) Ensure 'Scan all downloaded files and attachments' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableIOAVProtection" ` + | Select-Object -ExpandProperty "DisableIOAVProtection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant" + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.3" + Task = "(L1) Ensure 'Turn off real-time protection' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.4" + Task = "(L1) Ensure 'Turn on behavior monitoring' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableBehaviorMonitoring" ` + | Select-Object -ExpandProperty "DisableBehaviorMonitoring" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.10.5" + Task = "(L1) Ensure 'Turn on script scanning' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableScriptScanning" ` + | Select-Object -ExpandProperty "DisableScriptScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.11.1.1.1" + Task = "(L2) Ensure 'Configure Brute-Force Protection aggressiveness' is set to 1 - 'Enabled: Medium' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection" ` + -Name "BruteForceProtectionAggressiveness" ` + | Select-Object -ExpandProperty "BruteForceProtectionAggressiveness" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.11.1.1.2" + Task = "(L1) Ensure 'Configure Remote Encryption Protection Mode' is set to 2 - 'Enabled: Audit' or 1 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Brute Force Protection" ` + -Name "BruteForceProtectionConfiguredState" ` + | Select-Object -ExpandProperty "BruteForceProtectionConfiguredState" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.11.1.2.1" + Task = "(L2) Ensure 'Configure how aggressively Remote Encryption Protection blocks threats' is set to 1 - 'Enabled: Medium' or 2 - higher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Remediation\Behavioral Network Blocks\Remote Encryption Protection" ` + -Name "RemoteEncryptionProtectionAggressiveness" ` + | Select-Object -ExpandProperty "RemoteEncryptionProtectionAggressiveness" + + if (($regValue -ne 1) -and ($regValue -ne 2)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or x == 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.12.1" + Task = "(L2) Ensure 'Configure Watson events' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" ` + -Name "DisableGenericReports" ` + | Select-Object -ExpandProperty "DisableGenericReports" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.1" + Task = "(L1) Ensure 'Scan excluded files and directories during quick scans' is set to 'Enabled: 1'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "QuickScanIncludeExclusions" ` + | Select-Object -ExpandProperty "QuickScanIncludeExclusions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.2" + Task = "(L1) Ensure 'Scan packed executables' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisablePackedExeScanning" ` + | Select-Object -ExpandProperty "DisablePackedExeScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.3" + Task = "(L1) Ensure 'Scan removable drives' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableRemovableDriveScanning" ` + | Select-Object -ExpandProperty "DisableRemovableDriveScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.4" + Task = "(L1) Ensure 'Trigger a quick scan after X days without any scans' is set to 'Enabled: 7'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DaysUntilAggressiveCatchupQuickScan" ` + | Select-Object -ExpandProperty "DaysUntilAggressiveCatchupQuickScan" + + if ($regValue -ne 7) { + return @{ + Message = "Registry value is '$regValue'. Expected: 7" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.13.5" + Task = "(L1) Ensure 'Turn on e-mail scanning' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan" ` + -Name "DisableEmailScanning" ` + | Select-Object -ExpandProperty "DisableEmailScanning" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.16" + Task = "(L1) Ensure 'Configure detection for potentially unwanted applications' is set to 'Enabled: Block'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "PUAProtection" ` + | Select-Object -ExpandProperty "PUAProtection" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.17" + Task = "(L1) Ensure 'Control whether exclusions are visible to local users' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" ` + -Name "HideExclusionsFromLocalUsers" ` + | Select-Object -ExpandProperty "HideExclusionsFromLocalUsers" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.51.1" + Task = "(L1) Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive" ` + -Name "DisableFileSyncNGSC" ` + | Select-Object -ExpandProperty "DisableFileSyncNGSC" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.56.1" + Task = "(L2) Ensure 'Turn off Push To Install service' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall" ` + -Name "DisablePushToInstall" ` + | Select-Object -ExpandProperty "DisablePushToInstall" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.2.2" + Task = "(L1) Ensure 'Do not allow passwords to be saved' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DisablePasswordSaving" ` + | Select-Object -ExpandProperty "DisablePasswordSaving" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.2.1" + Task = "(L2) Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fSingleSessionPerUser" ` + | Select-Object -ExpandProperty "fSingleSessionPerUser" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.1" + Task = "(L2) Ensure 'Allow UI Automation redirection' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "EnableUiaRedirection" ` + | Select-Object -ExpandProperty "EnableUiaRedirection" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.2" + Task = "(L2) Ensure 'Do not allow COM port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCcm" ` + | Select-Object -ExpandProperty "fDisableCcm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.3" + Task = "(L1) Ensure 'Do not allow drive redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableCdm" ` + | Select-Object -ExpandProperty "fDisableCdm" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.4" + Task = "(L2) Ensure 'Do not allow location redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLocationRedir" ` + | Select-Object -ExpandProperty "fDisableLocationRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.5" + Task = "(L2) Ensure 'Do not allow LPT port redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableLPT" ` + | Select-Object -ExpandProperty "fDisableLPT" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.6" + Task = "(L2) Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisablePNPRedir" ` + | Select-Object -ExpandProperty "fDisablePNPRedir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.7" + Task = "(L2) Ensure 'Do not allow WebAuthn redirection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fDisableWebAuthn" ` + | Select-Object -ExpandProperty "fDisableWebAuthn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.3.8" + Task = "(L2) Ensure 'Restrict clipboard transfer from server to client' is set to 'Enabled: Disable clipboard transfers from server to client'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SCClipLevel" ` + | Select-Object -ExpandProperty "SCClipLevel" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.1" + Task = "(L1) Ensure 'Always prompt for password upon connection' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fPromptForPassword" ` + | Select-Object -ExpandProperty "fPromptForPassword" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.2" + Task = "(L1) Ensure 'Require secure RPC communication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "fEncryptRPCTraffic" ` + | Select-Object -ExpandProperty "fEncryptRPCTraffic" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.3" + Task = "(L1) Ensure 'Require use of specific security layer for remote (RDP) connections' is set to 'Enabled: SSL'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "SecurityLayer" ` + | Select-Object -ExpandProperty "SecurityLayer" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.4" + Task = "(L1) Ensure 'Require user authentication for remote connections by using Network Level Authentication' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "UserAuthentication" ` + | Select-Object -ExpandProperty "UserAuthentication" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.9.5" + Task = "(L1) Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MinEncryptionLevel" ` + | Select-Object -ExpandProperty "MinEncryptionLevel" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.10.1" + Task = "(L2) Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less, but not Never (0)'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxIdleTime" ` + | Select-Object -ExpandProperty "MaxIdleTime" + + if (($regValue -gt 900000 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900000 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.10.2" + Task = "(L2) Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxDisconnectionTime" ` + | Select-Object -ExpandProperty "MaxDisconnectionTime" + + if ($regValue -ne 60000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 60000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.11.1" + Task = "(L1) Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "DeleteTempDirsOnExit" ` + | Select-Object -ExpandProperty "DeleteTempDirsOnExit" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.57.3.11.2" + Task = "(L1) Ensure 'Do not use temporary folders per session' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "PerSessionTempDir" ` + | Select-Object -ExpandProperty "PerSessionTempDir" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.1" + Task = "(L1) Ensure 'Prevent downloading of enclosures' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "DisableEnclosureDownload" ` + | Select-Object -ExpandProperty "DisableEnclosureDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.58.2" + Task = "(L1) Ensure 'Turn on Basic feed authentication over HTTP' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds" ` + -Name "AllowBasicAuthInClear" ` + | Select-Object -ExpandProperty "AllowBasicAuthInClear" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.2" + Task = "(L2) Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowCloudSearch" ` + | Select-Object -ExpandProperty "AllowCloudSearch" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Compliant. Registry value not found." + Status = "True" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Compliant. Registry key not found." + Status = "True" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.3" + Task = "(L1) Ensure 'Allow indexing of encrypted files' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "AllowIndexingEncryptedStoresOrItems" ` + | Select-Object -ExpandProperty "AllowIndexingEncryptedStoresOrItems" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.59.4" + Task = "(L2) Ensure 'Allow search highlights' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search" ` + -Name "EnableDynamicContentInWSB" ` + | Select-Object -ExpandProperty "EnableDynamicContentInWSB" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.63.1" + Task = "(L2) Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" ` + -Name "NoGenTicket" ` + | Select-Object -ExpandProperty "NoGenTicket" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.2.1 A" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (EnableSmartScreen)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "EnableSmartScreen" ` + | Select-Object -ExpandProperty "EnableSmartScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.76.2.1 B" + Task = "(L1) Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' (ShellSmartScreenLevel)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" ` + -Name "ShellSmartScreenLevel" ` + | Select-Object -ExpandProperty "ShellSmartScreenLevel" + + if ($regValue -ne "Block") { + return @{ + Message = "Registry value is '$regValue'. Expected: Block" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.1" + Task = "(L2) Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowSuggestedAppsInWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowSuggestedAppsInWindowsInkWorkspace" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.80.2" + Task = "(L1) Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Enabled: Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" ` + -Name "AllowWindowsInkWorkspace" ` + | Select-Object -ExpandProperty "AllowWindowsInkWorkspace" + + if (($regValue -ne 1) -and ($regValue -ne 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1 or x == 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.1" + Task = "(L1) Ensure 'Allow user control over installs' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "EnableUserControl" ` + | Select-Object -ExpandProperty "EnableUserControl" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.2" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.81.3" + Task = "(L2) Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "SafeForScripting" ` + | Select-Object -ExpandProperty "SafeForScripting" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.82.1" + Task = "(L1) Ensure 'Configure the transmission of the user's password in the content of MPR notifications sent by winlogon.' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "EnableMPR" ` + | Select-Object -ExpandProperty "EnableMPR" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.82.2" + Task = "(L1) Ensure 'Sign-in and lock last interactive user automatically after a restart' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` + -Name "DisableAutomaticRestartSignOn" ` + | Select-Object -ExpandProperty "DisableAutomaticRestartSignOn" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.87.1" + Task = "(L2) Ensure 'Turn on PowerShell Script Block Logging' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ` + -Name "EnableScriptBlockLogging" ` + | Select-Object -ExpandProperty "EnableScriptBlockLogging" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.87.2" + Task = "(L2) Ensure 'Turn on PowerShell Transcription' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" ` + -Name "EnableTranscripting" ` + | Select-Object -ExpandProperty "EnableTranscripting" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.2" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.1.3" + Task = "(L1) Ensure 'Disallow Digest authentication' is set to 'Enabled' (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" ` + -Name "AllowDigest" ` + | Select-Object -ExpandProperty "AllowDigest" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.1" + Task = "(L1) Ensure 'Allow Basic authentication' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowBasic" ` + | Select-Object -ExpandProperty "AllowBasic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.2" + Task = "(L2) Ensure 'Allow remote server management through WinRM' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowAutoConfig" ` + | Select-Object -ExpandProperty "AllowAutoConfig" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.3" + Task = "(L1) Ensure 'Allow unencrypted traffic' is set to 'Disabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "AllowUnencryptedTraffic" ` + | Select-Object -ExpandProperty "AllowUnencryptedTraffic" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.89.2.4" + Task = "(L1) Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' (Service)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" ` + -Name "DisableRunAs" ` + | Select-Object -ExpandProperty "DisableRunAs" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.90.1" + Task = "(L2) Ensure 'Allow Remote Shell Access' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS" ` + -Name "AllowRemoteShellAccess" ` + | Select-Object -ExpandProperty "AllowRemoteShellAccess" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.92.2.1" + Task = "(L1) Ensure 'Prevent users from modifying settings' is set to 'Enabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection" ` + -Name "DisallowExploitProtectionOverride" ` + | Select-Object -ExpandProperty "DisallowExploitProtectionOverride" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.1.1" + Task = "(L1) Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoRebootWithLoggedOnUsers" ` + | Select-Object -ExpandProperty "NoAutoRebootWithLoggedOnUsers" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.1" + Task = "(L1) Ensure 'Configure Automatic Updates' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "NoAutoUpdate" ` + | Select-Object -ExpandProperty "NoAutoUpdate" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.2.2" + Task = "(L1) Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" ` + -Name "ScheduledInstallDay" ` + | Select-Object -ExpandProperty "ScheduledInstallDay" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.1" + Task = "(L1) Ensure 'Manage preview builds' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "ManagePreviewBuildsPolicyValue" ` + | Select-Object -ExpandProperty "ManagePreviewBuildsPolicyValue" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.2 A" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdates" ` + | Select-Object -ExpandProperty "DeferFeatureUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.2 B" + Task = "(L1) Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: 180 or more days' (DeferFeatureUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferFeatureUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferFeatureUpdatesPeriodInDays" + + if (($regValue -lt 180 -or $regValue -gt 365)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x >= 180 and x <= 365" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.3 A" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdates)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdates" ` + | Select-Object -ExpandProperty "DeferQualityUpdates" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.93.4.3 B" + Task = "(L1) Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' (DeferQualityUpdatesPeriodInDays)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" ` + -Name "DeferQualityUpdatesPeriodInDays" ` + | Select-Object -ExpandProperty "DeferQualityUpdatesPeriodInDays" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.5.1.1" + Task = "(L1) Ensure 'Turn off toast notifications on the lock screen' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ` + -Name "NoToastApplicationNotificationOnLockScreen" ` + | Select-Object -ExpandProperty "NoToastApplicationNotificationOnLockScreen" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.6.6.1.1" + Task = "(L2) Ensure 'Turn off Help Experience Improvement Program' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Assistance\Client\1.0" ` + -Name "NoImplicitFeedback" ` + | Select-Object -ExpandProperty "NoImplicitFeedback" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.5.1" + Task = "(L1) Ensure 'Do not preserve zone information in file attachments' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "SaveZoneInformation" ` + | Select-Object -ExpandProperty "SaveZoneInformation" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.5.2" + Task = "(L1) Ensure 'Notify antivirus programs when opening attachments' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments" ` + -Name "ScanWithAntiVirus" ` + | Select-Object -ExpandProperty "ScanWithAntiVirus" + + if ($regValue -ne 3) { + return @{ + Message = "Registry value is '$regValue'. Expected: 3" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.1" + Task = "(L1) Ensure 'Configure Windows spotlight on lock screen' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "ConfigureWindowsSpotlight" ` + | Select-Object -ExpandProperty "ConfigureWindowsSpotlight" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.2" + Task = "(L1) Ensure 'Do not suggest third-party content in Windows spotlight' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableThirdPartySuggestions" ` + | Select-Object -ExpandProperty "DisableThirdPartySuggestions" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.3" + Task = "(L2) Ensure 'Do not use diagnostic data for tailored experiences' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableTailoredExperiencesWithDiagnosticData" ` + | Select-Object -ExpandProperty "DisableTailoredExperiencesWithDiagnosticData" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.4" + Task = "(L2) Ensure 'Turn off all Windows spotlight features' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableWindowsSpotlightFeatures" ` + | Select-Object -ExpandProperty "DisableWindowsSpotlightFeatures" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.8.5" + Task = "(L1) Ensure 'Turn off Spotlight collection on Desktop' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ` + -Name "DisableSpotlightCollectionOnDesktop" ` + | Select-Object -ExpandProperty "DisableSpotlightCollectionOnDesktop" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.26.1" + Task = "(L1) Ensure 'Prevent users from sharing files within their profile.' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" ` + -Name "NoInplaceSharing" ` + | Select-Object -ExpandProperty "NoInplaceSharing" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.44.1" + Task = "(L1) Ensure 'Always install with elevated privileges' is set to 'Disabled' (AlwaysInstallElevated)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\Installer" ` + -Name "AlwaysInstallElevated" ` + | Select-Object -ExpandProperty "AlwaysInstallElevated" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "19.7.46.2.1" + Task = "(L2) Ensure 'Prevent Codec Download' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\WindowsMediaPlayer" ` + -Name "PreventCodecDownload" ` + | Select-Object -ExpandProperty "PreventCodecDownload" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#SecurityOptions.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#SecurityOptions.ps1 new file mode 100644 index 0000000..89e9339 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#SecurityOptions.ps1 @@ -0,0 +1,133 @@ +[AuditTest] @{ + Id = "2.3.1.1" + Task = "(L1) Ensure 'Accounts: Guest account status' is set to 'Disabled' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["EnableGuestAccount"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'EnableGuestAccount' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.3" + Task = "(L1) Configure 'Accounts: Rename administrator account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewAdministratorName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$") { + return @{ + Message = "'NewAdministratorName' currently set to: $setOption. Expected: ^(?=.{1,20}$)(?i)(?!.*\b(?:Administrator)\b).*$" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1.4" + Task = "(L1) Configure 'Accounts: Rename guest account'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["NewGuestName"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -notmatch "^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$") { + return @{ + Message = "'NewGuestName' currently set to: $setOption. Expected: ^(?=.{1,20}$)(?i)(?!.*\b(?:Guest|Gast)\b).*$" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.10.1" + Task = "(L1) Ensure 'Network access: Allow anonymous SID/Name translation' is set to 'Disabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["LSAAnonymousNameLookup"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 0) { + return @{ + Message = "'LSAAnonymousNameLookup' currently set to: $setOption. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.6" + Task = "(L1) Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'" + Test = { + $securityOption = Get-AuditResource "WindowsSecurityPolicy" + $setOption = $securityOption['System Access']["ForceLogoffWhenHourExpire"] + + if ($null -eq $setOption) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + if ($setOption -ne 1) { + return @{ + Message = "'ForceLogoffWhenHourExpire' currently set to: $setOption. Expected: 1" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#UserRights.ps1 b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#UserRights.ps1 new file mode 100644 index 0000000..4853eac --- /dev/null +++ b/ATAPAuditor/AuditGroups/Microsoft Windows Server 2025-CIS-1.0.0#UserRights.ps1 @@ -0,0 +1,1987 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$hyperVStatus = CheckHyperVStatus +# Common +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Convert Domaingroups to german + $language = Get-UICulture + if ($language.Name -match "de-DE") { + if ($name -eq "Enterprise Admins") { + $name = "Organisations-Admins" + } + elseif ($name -eq "Domain Admins") { + $name = "Domänen-Admins" + } + } + + # Convert friendlynames to SID + $map = @{ + "Administrators" = "S-1-5-32-544" + "Guests" = "S-1-5-32-546" + "Local account" = "S-1-5-113" + "Local Service" = "S-1-5-19" + "Network Service" = "S-1-5-20" + "NT AUTHORITY\Authenticated Users" = "S-1-5-11" + "Remote Desktop Users" = "S-1-5-32-555" + "Service" = "S-1-5-6" + "Users" = "S-1-5-32-545" + "NT VIRTUAL MACHINE\Virtual Machines" = "S-1-5-83-0" + } + + if ($map.ContainsKey($name)) { + $name = $map[$name] + } + + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "S-1-5-83-0" -and + (Get-WindowsOptionalFeature -Online -FeatureName "Microsoft-Hyper-V").State -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + if ($sidAccount.Translate([System.Security.Principal.NTAccount]) -eq "NULL SID") { + return @{ + Account = $null + Sid = $sidAccount.Value + } + } + else { + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + } + catch { + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} + +# Tests +[AuditTest] @{ + Id = "2.2.1" + Task = "(L1) Ensure 'Access Credential Manager as a trusted caller' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTrustedCredManAccessPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTrustedCredManAccessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTrustedCredManAccessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Authenticated Users, ENTERPRISE DOMAIN CONTROLLERS' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-11" + "S-1-5-32-544" + "S-1-5-9" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.3" + Task = "(L1) Ensure 'Access this computer from the network' is set to 'Administrators, Authenticated Users' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-11" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeNetworkLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.4" + Task = "(L1) Ensure 'Act as part of the operating system' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTcbPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTcbPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTcbPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.5" + Task = "(L1) Ensure 'Add workstations to domain' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeMachineAccountPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeMachineAccountPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeMachineAccountPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.6" + Task = "(L1) Ensure 'Adjust memory quotas for a process' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseQuotaPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseQuotaPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseQuotaPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.7" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators, ENTERPRISE DOMAIN CONTROLLERS' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-9" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.8" + Task = "(L1) Ensure 'Allow log on locally' is set to 'Administrators' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.9" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.10" + Task = "(L1) Ensure 'Allow log on through Remote Desktop Services' is set to 'Administrators, Remote Desktop Users' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-32-555" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeRemoteInteractiveLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.11" + Task = "(L1) Ensure 'Back up files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBackupPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBackupPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBackupPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.12" + Task = "(L1) Ensure 'Change the system time' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemtimePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-19" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemtimePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemtimePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.13" + Task = "(L1) Ensure 'Change the time zone' is set to 'Administrators, LOCAL SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTimeZonePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTimeZonePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTimeZonePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.14" + Task = "(L1) Ensure 'Create a pagefile' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePagefilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePagefilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePagefilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.15" + Task = "(L1) Ensure 'Create a token object' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateTokenPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.16" + Task = "(L1) Ensure 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateGlobalPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateGlobalPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateGlobalPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.17" + Task = "(L1) Ensure 'Create permanent shared objects' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreatePermanentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreatePermanentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreatePermanentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.18" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if ($hyperVStatus -ne "Enabled") { + [AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators [Hyper-V-Feature NOT installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else { + [AuditTest] @{ + Id = "2.2.19" + Task = "(L1) Ensure 'Create symbolic links' is set to 'Administrators, NT VIRTUAL MACHINE\Virtual Machines' [Hyper-V-Feature installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeCreateSymbolicLinkPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-83-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeCreateSymbolicLinkPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeCreateSymbolicLinkPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.20" + Task = "(L1) Ensure 'Debug programs' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDebugPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + + if ($unexpectedUsers.Count -gt 0) { + $messages = @() + $messages += "The user right 'SeDebugPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + $message = $messages -join [System.Environment]::NewLine + return @{ + Status = "False" + Message = $message + } + } + #No UserRights on System comparing to publisher recommendation + if ($null -eq $currentUserRights -and $identityAccounts.Count -gt 0) { + return @{ + Status = "True" + Message = "Compliant - No UserRights are assigned to this policy. This configuration is even more secure than publisher recommendation." + } + } + #Less UserRights on System comparing to publisher recommendation + if ($currentUserRights.Count -lt $identityAccounts.Count) { + $users = "" + foreach ($currentUser in $currentUserRights) { + $users += $currentUser.Values + } + return @{ + Status = "True" + Message = "Compliant - Positive Deviation to publisher. Less UserRights are assigned to this policy than expected: $($users)" + } + } + #Same UserRights on System comparing to publisher recommendation + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.21" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.22" + Task = "(L1) Ensure 'Deny access to this computer from the network' to include 'Guests, Local account and member of Administrators group' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyNetworkLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + "S-1-5-114" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyNetworkLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.23" + Task = "(L1) Ensure 'Deny log on as a batch job' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.24" + Task = "(L1) Ensure 'Deny log on as a service' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyServiceLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyServiceLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.25" + Task = "(L1) Ensure 'Deny log on locally' to include 'Guests'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.26" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' to include 'Guests' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.27" + Task = "(L1) Ensure 'Deny log on through Remote Desktop Services' is set to 'Guests, Local account' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeDenyRemoteInteractiveLogonRight"] + $identityAccounts = @( + "S-1-5-32-546" + "S-1-5-113" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($missingUsers.Count -gt 0)) { + $messages = @() + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeDenyRemoteInteractiveLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.28" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'Administrators' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.29" + Task = "(L1) Ensure 'Enable computer and user accounts to be trusted for delegation' is set to 'No One' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeEnableDelegationPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeEnableDelegationPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeEnableDelegationPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.30" + Task = "(L1) Ensure 'Force shutdown from a remote system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRemoteShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRemoteShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRemoteShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +$adfsModule = Get-Module -Name ADFS +if ($null -eq $adfsModule) { + [AuditTest] @{ + Id = "2.2.31 " + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE' [ADFS-ROLE NOT installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else { + [AuditTest] @{ + Id = "2.2.31" + Task = "(L1) Ensure 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE' [ADFS-ROLE installed]" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAuditPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-80-1321940109-3370001082-3650459431-215109509-2472514016" + "S-1-5-80-2246541699-21809830-3603976364-117610243-975697593" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAuditPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAuditPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.32" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +if ((Get-WindowsFeature -Name web-server).installed -ne $true) { + [AuditTest] @{ + Id = "2.2.33 A" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE' [IIS Role NOT installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +else { + [AuditTest] @{ + Id = "2.2.33 B" + Task = "(L1) Ensure 'Impersonate a client after authentication' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE, IIS_IUSRS' [IIS Role installed] (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeImpersonatePrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + "S-1-5-32-544" + "S-1-5-32-568" + "S-1-5-6" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeImpersonatePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeImpersonatePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +[AuditTest] @{ + Id = "2.2.34" + Task = "(L1) Ensure 'Increase scheduling priority' is set to 'Administrators, Window Manager\Window Manager Group'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeIncreaseBasePriorityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-90-0" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeIncreaseBasePriorityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeIncreaseBasePriorityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.35" + Task = "(L1) Ensure 'Load and unload device drivers' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLoadDriverPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLoadDriverPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLoadDriverPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.36" + Task = "(L1) Ensure 'Lock pages in memory' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeLockMemoryPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeLockMemoryPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeLockMemoryPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.37" + Task = "(L2) Ensure 'Log on as a batch job' is set to 'Administrators' (DC Only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeBatchLogonRight"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeBatchLogonRight' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeBatchLogonRight' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.38" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators' and (when Exchange is running in the environment) 'Exchange Servers' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.39" + Task = "(L1) Ensure 'Manage auditing and security log' is set to 'Administrators' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.40" + Task = "(L1) Ensure 'Modify an object label' is set to 'No One'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRelabelPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRelabelPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRelabelPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.41" + Task = "(L1) Ensure 'Modify firmware environment values' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemEnvironmentPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemEnvironmentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemEnvironmentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.42" + Task = "(L1) Ensure 'Perform volume maintenance tasks' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeManageVolumePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeManageVolumePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeManageVolumePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.43" + Task = "(L1) Ensure 'Profile single process' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeProfileSingleProcessPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeProfileSingleProcessPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeProfileSingleProcessPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.44" + Task = "(L1) Ensure 'Profile system performance' is set to 'Administrators, NT SERVICE\WdiServiceHost'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSystemProfilePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + "S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSystemProfilePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSystemProfilePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.45" + Task = "(L1) Ensure 'Replace a process level token' is set to 'LOCAL SERVICE, NETWORK SERVICE'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeAssignPrimaryTokenPrivilege"] + $identityAccounts = @( + "S-1-5-19" + "S-1-5-20" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeAssignPrimaryTokenPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeAssignPrimaryTokenPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.46" + Task = "(L1) Ensure 'Restore files and directories' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeRestorePrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeRestorePrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeRestorePrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.47" + Task = "(L1) Ensure 'Shut down the system' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeShutdownPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeShutdownPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeShutdownPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.48" + Task = "(L1) Ensure 'Synchronize directory service data' is set to 'No One' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSyncAgentPrivilege"] + $identityAccounts = @( + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSyncAgentPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSyncAgentPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} +[AuditTest] @{ + Id = "2.2.49" + Task = "(L1) Ensure 'Take ownership of files or other objects' is set to 'Administrators'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeTakeOwnershipPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeTakeOwnershipPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeTakeOwnershipPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } +} diff --git a/ATAPAuditor/AuditGroups/RSSeverityTests.ps1 b/ATAPAuditor/AuditGroups/RSSeverityTests.ps1 new file mode 100644 index 0000000..d865c80 --- /dev/null +++ b/ATAPAuditor/AuditGroups/RSSeverityTests.ps1 @@ -0,0 +1,2509 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$windefrunning = CheckWindefRunning +. "$RootPath\Helpers\Firewall.ps1" +$domainRole = (Get-CimInstance -Class Win32_ComputerSystem).DomainRole +$listOfWeakCipherSuites = getListOfWeakCipherSuites +$listOfInsecureCipherSuites = getListOfInsecureCipherSuites +[AuditTest] @{ + Id = "1.1.7" + Task = "Ensure 'Store passwords using reversible encryption' is set to 'Disabled'" + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $setPolicy = $securityPolicy['System Access']["ClearTextPassword"] + + if ($null -eq $setPolicy) { + return @{ + Message = "Currently not set." + Status = "False" + } + } + $setPolicy = [long]$setPolicy + + if ($setPolicy -ne 0) { + return @{ + Message = "'ClearTextPassword' currently set to: $setPolicy. Expected: 0" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +if ($domainRole -eq 3) { + [AuditTest] @{ + Id = "2.2.38" + Task = "Ensure 'Manage auditing and security log' is set to 'Administrators' (MS only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Server" } + ) + Test = { + $securityPolicy = Get-AuditResource "WindowsSecurityPolicy" + $currentUserRights = $securityPolicy["Privilege Rights"]["SeSecurityPrivilege"] + $identityAccounts = @( + "S-1-5-32-544" + ) | ConvertTo-NTAccountUser | Where-Object { $null -ne $_ } + + $unexpectedUsers = $currentUserRights.Account | Where-Object { $_ -notin $identityAccounts.Account } + $missingUsers = $identityAccounts.Account | Where-Object { $_ -notin $currentUserRights.Account } + + if (($unexpectedUsers.Count -gt 0) -or ($missingUsers.Count -gt 0)) { + $messages = @() + if ($unexpectedUsers.Count -gt 0) { + $messages += "The user right 'SeSecurityPrivilege' contains following unexpected users: " + ($unexpectedUsers -join ", ") + } + if ($missingUsers.Count -gt 0) { + $messages += "The user 'SeSecurityPrivilege' setting does not contain the following users: " + ($missingUsers -join ", ") + } + $message = $messages -join [System.Environment]::NewLine + + return @{ + Status = "False" + Message = $message + } + } + + return @{ + Status = "True" + Message = "Compliant" + } + } + } +} +if ($domainRole -ge 4) { + [AuditTest] @{ + Id = "2.3.5.2" + Task = "Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing' (DC only)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters" ` + -Name "LDAPServerIntegrity" ` + | Select-Object -ExpandProperty "LDAPServerIntegrity" + + if ($regValue -ne 2) { + return @{ + Message = "Registry value is '$regValue'. Expected: 2" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } + } +} +[AuditTest] @{ + Id = "2.3.11.4" + Task = "Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" ` + -Name "SupportedEncryptionTypes" ` + | Select-Object -ExpandProperty "SupportedEncryptionTypes" + + if (($regValue -ne 2147483644) -and ($regValue -ne 2147483640)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x == 2147483644 or x == 2147483640" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.11.5" + Task = "Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa" ` + -Name "NoLMHash" ` + | Select-Object -ExpandProperty "NoLMHash" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "9.1.7" + Task = "Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogDroppedPackets" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} +[AuditTest] @{ + Id = "9.1.8" + Task = "Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Member Workstation", "Member Server", "Primary Domain Controller", "Backup Domain Controller" } + ) + Test = { + $path1 = "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging" + $path2 = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging" + $key = "LogSuccessfulConnections" + $expectedValue = 1; + $profileType = "Domain" + $result = $path1, $path2 | Test-FirewallPaths -Key $key -ExpectedValue $expectedValue -ProfileType $profileType + return @{ + Message = $($result.Message) + Status = $($result.Status) + } + } +} + + + +[AuditTest] @{ + Id = "18.3.3" + Task = "Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10" ` + -Name "Start" ` + | Select-Object -ExpandProperty "Start" + + if ($regValue -ne 4) { + return @{ + Message = "Registry value is '$regValue'. Expected: 4" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.3.3" + Task = "Ensure 'Configure SMB v1 server' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` + -Name "SMB1" ` + | Select-Object -ExpandProperty "SMB1" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} + + + +[AuditTest] @{ + Id = "18.3.6" + Task = "Ensure 'WDigest Authentication' is set to 'Disabled'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" ` + -Name "UseLogonCredential" ` + | Select-Object -ExpandProperty "UseLogonCredential" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} + +[AuditTest] @{ + Id = "18.6.2" + Task = "Ensure 'Point and Print Restrictions: When installing drivers for a new connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "NoWarningNoElevationOnInstall" ` + | Select-Object -ExpandProperty "NoWarningNoElevationOnInstall" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.6.3" + Task = "Ensure 'Point and Print Restrictions: When updating drivers for an existing connection' is set to 'Enabled: Show warning and elevation prompt'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" ` + -Name "UpdatePromptSettings" ` + | Select-Object -ExpandProperty "UpdatePromptSettings" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.9.2" + Task = "Ensure 'Turn off real-time protection' is set to 'Disabled'" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection" ` + -Name "DisableRealtimeMonitoring" ` + | Select-Object -ExpandProperty "DisableRealtimeMonitoring" + + if ($regValue -eq 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1.2 A" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office communication application from creating child processes)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "26190899-1602-49e8-8b27-eb1d0a1ce869" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1.2 B" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from creating executable content)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "3b576869-a4ec-4529-8536-b80a7769e899" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1.2 C" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block execution of potentially obfuscated scripts)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1.2 D" + Task = "Ensure 'Configure Attack Surface Reduction rules: Block Office applications from injecting code into other processes' is configured" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1.2 E" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Adobe Reader from creating child processes)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1.2 F" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Win32 API calls from Office macro)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1.2 G" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block credential stealing from the Windows local security authority subsystem (lsass.exe))" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1.2 H" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block untrusted and unsigned processes that run from USB)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1.2 I" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block executable content from email client and webmail)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1.2 J" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block JavaScript or VBScript from launching downloaded executable content)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d3e037e1-3eb8-44c8-a917-57927947596d" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1.2 K" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block Office applications from creating child processes)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "d4f940ab-401b-4efc-aadc-ad5f3c50688a" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.47.5.1.2 L" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block persistence through WMI event subscription)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "e6db77e5-3df2-4cf1-b95a-636979351e5b" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.10.43.6.1.2 M" + Task = "Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is configured (Block abuse of exploited vulnerable signed drivers)" + Test = { + try { + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $regValue = 0; + $regValueTwo = 0; + $Path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest1 = Test-ASRRules -Path $Path -Value $Value + if ($asrTest1) { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path $Path ` + -Name $Value ` + | Select-Object -ExpandProperty $Value + } + + $Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + $Value2 = "56a863a9-875e-4185-98a7-b882c64b5ce5" + + $asrTest2 = Test-ASRRules -Path $Path2 -Value $Value2 + if ($asrTest2) { + $regValueTwo = Get-ItemProperty -ErrorAction Stop ` + -Path $Path2 ` + -Name $Value2 ` + | Select-Object -ExpandProperty $Value2 + } + + if ($regValue -ne 1 -and $regValueTwo -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.10.1" + Task = "Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxIdleTime" ` + | Select-Object -ExpandProperty "MaxIdleTime" + + if (($regValue -gt 900000 -or $regValue -eq 0)) { + return @{ + Message = "Registry value is '$regValue'. Expected: x <= 900000 and x != 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "18.9.58.3.10.2" + Task = "Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ` + -Name "MaxDisconnectionTime" ` + | Select-Object -ExpandProperty "MaxDisconnectionTime" + + if ($regValue -ne 60000) { + return @{ + Message = "Registry value is '$regValue'. Expected: 60000" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.1" + Task = "Disable SSLv2 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "Disable SSLv2 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "Disable SSLv2 Protocol (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "Disable SSLv2 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "Disable SSLv3 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "Disable SSLv3 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.3" + Task = "Disable SSLv3 Protocol (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.2.4" + Task = "Disable SSLv3 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.1" + Task = "Disable TLS1.0 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.2" + Task = "Disable TLS1.0 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.3" + Task = "Disable TLS1.0 Protocol (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.4" + Task = "Disable TLS1.0 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.4.1" + Task = "Disable TLS1.1 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.4.2" + Task = "Disable TLS1.1 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.4.3" + Task = "Disable TLS1.1 Protocol (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.4.4" + Task = "Disable TLS1.1 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.5.1" + Task = "Enable TLS1.2 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.5.2" + Task = "Enable TLS1.2 Protocol (Server Default)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.1" + Task = "Disable NULL Cipher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\NULL" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.2" + Task = "Disable DES Cipher Suite" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\DES 56/56" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.1" + Task = "Disable RC4 Cipher Suite - 40/128" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.2" + Task = "Disable RC4 Cipher Suite - 56/128" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.3" + Task = "Disable RC4 Cipher Suite - 64/128" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 64/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.3.4" + Task = "Disable RC4 Cipher Suite - 128/128" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.4" + Task = "Disable AES 128/128 Cipher Suite" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\AES 128/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.5" + Task = "Enable AES 256/256 Cipher Suite" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\AES 256/256" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -eq 4294967295) { + return @{ + Message = "The current registry value is '$regValue', which is no longer supported by Microsoft. For more information, please refer to this link:
"` + + ''` + + 'Learn.microsoft.com - TLS, DTLS, and SSL protocol version settings' + Status = "False" + } + } + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "2.6" + Task = "Disable Triple DES Cipher Suite" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\Triple DES 168" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.1" + Task = "Disable SHA-1 hash" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Hashes\SHA" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.2" + Task = "Disable MD5 hash" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Hashes\MD5" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.1" + Task = "Configure Cipher Suite Ordering" + Test = { + #check if correct type + $typeTable = @{ + "String" = "String Value" + "Byte" = "Byte Value" + "Int32" = "DWORD (32-bit) Value" + "Int64" = "QWORD (64-bit) Value" + "String[]" = "Multi-String Value" + } + #Default status + $status = "Error" + + #Output + $verbInsecure = "rules have" + $verbWeak = "rules have" + + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002" ` + -Name "Functions" + $reference = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" + $res = $regValue.Functions.GetType().Name + + + $currentType = $typeTable[$res] + if ($res -ne [String]) { + return @{ + Message = "Wrong Registry type! Registry type is '$currentType'. Expected: 'String Value'" + Status = "False" + } + } + + #check if insecure or weak cipher is inside value + $regValues = $regValue.Split(',') + $regValues = $regValues -replace ' ', '' + $weakRulesFound = @() + $insecureRulesFound = @() + foreach ($element in $regValues) { + if ($listOfWeakCipherSuites.Contains($element)) { + $weakRulesFound += $element + } + if ($listOfInsecureCipherSuites.Contains($element)) { + $insecureRulesFound += $element + } + } + if ($insecureRulesFound.Count -eq 1) { $verbInsecure = "rule has" } + if ($weakRulesFound.Count -eq 1) { $verbWeak = "rule has" } + $insecureMessage = "$($insecureRulesFound.Count) insecure $($verbInsecure) been found! List of insecure rules:
" + $weakMessage = "$($weakRulesFound.Count) weak $($verbWeak) been found! List of weak rules:
" + + #Preparing message + foreach ($member in $weakRulesFound) { + $status = "Warning" + $weakMessage += "$($member)
" + } + foreach ($member in $insecureRulesFound) { + $status = "False" + $insecureMessage += "$($member)
" + } + #Combine or shorten message + if ($insecureRulesFound.Count -gt 0 -or $weakRulesFound.Count -gt 0) { + $message = "" + if ($weakRulesFound.Count -eq 0) { $weakMessage = "" } + if ($insecureRulesFound.Count -eq 0) { $insecureMessage = "" } + + $message = $insecureMessage + $weakMessage + return @{ + Message = $message + Status = $status + } + } + } + catch { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002" ` + -Name "Functions" + $reference = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" + $res = $regValue.Functions.GetType().Name + + $currentType = $typeTable[$res] + if ($res -ne [String[]]) { + return @{ + Message = "Wrong Registry type! Registry type is '$currentType'. Expected: 'Multi-String Value'" + Status = "False" + } + } + + #check if insecure or weak cipher is inside value + $regValues = $regValue -replace ' ', '' + $weakRulesFound = @() + $insecureRulesFound = @() + foreach ($element in $regValues) { + if ($listOfWeakCipherSuites.Contains($element)) { + $weakRulesFound += $element + } + if ($listOfInsecureCipherSuites.Contains($element)) { + $insecureRulesFound += $element + } + } + if ($insecureRulesFound.Count -eq 1) { $verbInsecure = "rule has" } + if ($weakRulesFound.Count -eq 1) { $verbWeak = "rule has" } + $insecureMessage = "$($insecureRulesFound.Count) insecure $($verbInsecure) been found! List of insecure rules:
" + $weakMessage = "$($weakRulesFound.Count) weak $($verbWeak) been found! List of weak rules:
" + + #Preparing message + foreach ($member in $weakRulesFound) { + $status = "Warning" + $weakMessage += "$($member)
" + } + foreach ($member in $insecureRulesFound) { + $status = "False" + $insecureMessage += "$($member)
" + } + #Combine or shorten message + if ($insecureRulesFound.Count -gt 0 -or $weakRulesFound.Count -gt 0) { + $message = "" + if ($weakRulesFound.Count -eq 0) { $weakMessage = "" } + if ($insecureRulesFound.Count -eq 0) { $insecureMessage = "" } + + $message = $insecureMessage + $weakMessage + return @{ + Message = $message + Status = $status + } + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/Red Hat Enterprise Linux 9-CIS-1.0.0.ps1 b/ATAPAuditor/AuditGroups/Red Hat Enterprise Linux 9-CIS-1.0.0.ps1 new file mode 100644 index 0000000..8bc1161 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Red Hat Enterprise Linux 9-CIS-1.0.0.ps1 @@ -0,0 +1,3832 @@ +$rcTrue = "True" +$rcCompliant = "Compliant" +$rcFalse = "False" +$rcNone = "None" +$rcNonCompliant = "Non-Compliant" +$rcNonCompliantManualReviewRequired = "Manual review required" +$rcCompliantIPv6isDisabled = "IPv6 is disabled" + +$retCompliant = @{ + Message = $rcCompliant + Status = $rcTrue +} +$retNonCompliant = @{ + Message = $rcNonCompliant + Status = $rcFalse +} +$retCompliantIPv6Disabled = @{ + Message = $rcCompliantIPv6isDisabled + Status = $rcTrue +} +$retNonCompliantManualReviewRequired = @{ + Message = $rcNonCompliantManualReviewRequired + Status = $rcNone +} + +$IPv6Status_script = grep -Pqs '^\h*0\b' /sys/module/ipv6/parameters/disable && echo "IPv6 is enabled" || echo "IPv6 is not enabled" +$IPv6Status = bash -c $IPv6Status_script +if ($IPv6Status -match "is enabled") { + $IPv6Status = "enabled" +} else { + $IPv6Status = "disabled" +} + +$parentPath = Split-Path -Parent -Path $PSScriptRoot +$scriptPath = $parentPath + "/Helpers/ShellScripts/RHEL9/" + + +### Chapter 1 - Initial Setup + + +[AuditTest] @{ + Id = "1.1.1.1" + Task = "Ensure mounting of squashfs filesystems is disabled" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_1111.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.1.2" + Task = "Ensure mounting of udf filesystems is disabled" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_1112.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.2.1" + Task = "Ensure /tmp is a separate partition" + Test = { + $result = findmnt --kernel /tmp | grep -E '\s/tmp\s' + if ($result -match "/tmp") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.2.2" + Task = "Ensure nodev option set on /tmp partition" + Test = { + $result = findmnt --kernel /tmp | grep nodev + if ($result -match "/tmp") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.2.3" + Task = "Ensure noexec option set on /tmp partition" + Test = { + $result = findmnt --kernel /tmp | grep noexec + if ($result -match "/tmp") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.2.4" + Task = "Ensure nosuid option set on /tmp partition" + Test = { + $result = findmnt --kernel /tmp | grep nosuid + if ($result -match "/tmp") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.3.1" + Task = "Ensure separate partition exists for /var" + Test = { + $result = findmnt --kernel /var + if ($result -match "/var") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.1.3.2" + Task = "Ensure nodev option set on /var partition" + Test = { + $result = findmnt --kernel /var | grep nodev + if ($result -match "/var") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.3.3" + Task = "Ensure nosuid option set on /var partition" + Test = { + $result = findmnt --kernel /var | grep nosuid + if ($result -match "/var") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.4.1" + Task = "Ensure separate partition exists for /var/tmp" + Test = { + $result = findmnt --kernel /var/tmp + if ($result -match "/var/tmp") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.4.2" + Task = "Ensure noexec option set on /var/tmp partition" + Test = { + $result = findmnt --kernel /var/tmp | grep noexec + if ($result -match "/var/tmp") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.4.3" + Task = "Ensure nosuid option set on /var/tmp partition" + Test = { + $result = findmnt --kernel /var/tmp | grep nosuid + if ($result -match "/var/tmp") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.4.4" + Task = "Ensure nodev option set on /var/tmp partition" + Test = { + $result = findmnt --kernel /var/tmp | grep nodev + if ($result -match "/tmp") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.5.1" + Task = "Ensure separate partition exists for /var/log" + Test = { + $result = findmnt --kernel /var/log + if ($result -match "/var/log") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.5.2" + Task = "Ensure nodev option set on /var/log" + Test = { + $result = findmnt --kernel /var/log | grep nodev + if ($result -match "/var/log") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.5.3" + Task = "Ensure noexec option set on /var/log" + Test = { + $result = findmnt --kernel /var/log | grep noexec + if ($result -match "/var/log") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.5.4" + Task = "Ensure nosuid option set on /var/log" + Test = { + $result = findmnt --kernel /var/log | grep nosuid + if ($result -match "/var/log") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.6.1" + Task = "Ensure separate partition exists for /var/log/audit" + Test = { + $result = findmnt --kernel /var/log/audit + if ($result -match "/var/log/audit") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.6.2" + Task = "Ensure noexec option set on /var/log/audit" + Test = { + $result = findmnt --kernel /var/log/audit | grep noexec + if ($result -match "/var/log/audit") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.6.3" + Task = "Ensure nodev option set on /var/log/audit" + Test = { + $result = findmnt --kernel /var/log/audit | grep nodev + if ($result -match "/var/log/audit") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.6.4" + Task = "Ensure nosuid option set on /var/log/audit" + Test = { + $result = findmnt --kernel /var/log/audit | grep nosuid + if ($result -match "/var/log/audit") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.7.1" + Task = "Ensure separate partition exists for /home" + Test = { + $result = findmnt --kernel /home + if ($result -match "/home") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.7.2" + Task = "Ensure nodev option set on /home" + Test = { + $result = findmnt --kernel /home | grep nodev + if ($result -match "/home") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.7.3" + Task = "Ensure nosuid option set on /home" + Test = { + $result = findmnt --kernel /home | grep nosuid + if ($result -match "/home") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.8.1" + Task = "Ensure /dev/shm is a separate partition" + Test = { + $result = findmnt --kernel /dev/shm + if ($result -match "/dev/shm") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.8.2" + Task = "Ensure nodev option set on /dev/shm partition" + Test = { + $result = mount | grep -E '\s/dev/shm\s' | grep nodev + if ($result -match "/dev/shm") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.8.3" + Task = "Ensure noexec option set on /dev/shm partition" + Test = { + $result = findmnt --kernel /dev/shm | grep noexec + if ($result -match "/dev/shm") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.8.4" + Task = "Ensure nosuid option set on /dev/shm partition" + Test = { + $result = findmnt --kernel /dev/shm | grep nosuid + if ($result -match "/dev/shm") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.9" + Task = "Disable USB Storage" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_119.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.2.1" + Task = "Ensure GPG keys are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "1.2.2" + Task = "Ensure gpgcheck is globally activated" + Test = { + $result = grep ^gpgcheck /etc/dnf/dnf.conf + if ($result -match "gpgcheck=1") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.2.3" + Task = "Ensure package manager repositories are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "1.2.4" + Task = "Ensure repo_gpgcheck is globally activated" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "1.3.1" + Task = "Ensure aide is installed" + Test = { + $result = rpm -q aide + if ($result -match "aide-") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.3.2" + Task = "Ensure filesystem integrity is regularly checked" + Test = { + $result1 = systemctl is-enabled aidecheck.service + $result2 = systemctl is-enabled aidecheck.timer + $result3 = systemctl status aidecheck.service + if ($result1 -match "enabled" -and $result2 -match "enabled" -and $result3 -match "Active:") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.3.3" + Task = "Ensure filesystem integrity is regularly checked" + Test = { + $result = grep -Ps -- '(\/sbin\/(audit|au)\H*\b)' /etc/aide.conf.d/*.conf /etc/aide.conf + if ($result -match "/sbin/auditctl p+i+n+u+g+s+b+acl+xattrs+sha512" -and + $result -match "/sbin/auditd p+i+n+u+g+s+b+acl+xattrs+sha512" -and + $result -match "/sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512" -and + $result -match "/sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512" -and + $result -match "/sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512" -and + $result -match "/sbin/augenrules p+i+n+u+g+s+b+acl+xattrs+sha512"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.4.1" + Task = "Ensure bootloader password is set" + Test = { + $result = awk -F. '/^\s*GRUB2_PASSWORD/ {print $1"."$2"."$3}' /boot/grub2/user.cfg + if ($result -match "GRUB2_PASSWORD=grub.pbkdf2.sha512") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.4.2" + Task = "Ensure permissions on bootloader config are configured" + Test = { + $result1 = stat -Lc "%n %#a %u/%U %g/%G" /boot/grub2/grub.cfg | grep '/boot/grub2/grub.cfg\s*0700\s*0/root\s*0/root' + $result2 = stat -Lc "%n %#a %u/%U %g/%G" /boot/grub2/grubenv | grep '/boot/grub2/grubenv\s*0600\s*0/root\s*0/root' + $result3 = stat -Lc "%n %#a %u/%U %g/%G" /boot/grub2/user.cfg | grep '/boot/grub2/user.cfg\s*0600\s*0/root\s*0/root' + if ($result1 -ne $null -and $result2 -ne $null -and $result3 -ne $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.5.1" + Task = "Ensure core dump storage is disabled" + Test = { + $result = grep -i '^\s*storage\s*=\s*none' /etc/systemd/coredump.conf + if ($result -match "Storage=none") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.5.2" + Task = "Ensure core dump backtraces are disabled" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + grep -Pi '^\h*ProcessSizeMax\h*=\h*0\b' /etc/systemd/coredump.conf || echo -e "\n- Audit results:\n FAIL\n - \"ProcessSizeMax\" is: \"$(grep -i 'ProcessSizeMax' /etc/systemd/coredump.conf)\"" +} +'@ + $result = bash -c $script_string + if ($result -match "FAIL") { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "1.5.3" + Task = "Ensure address space layout randomization (ASLR) is enabled" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_parlist="kernel.randomize_va_space=2" + l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)" + KPC() + { + l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)" + l_pafile="$(grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc)" + l_fafile="$(grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$l_krp" = "$l_kpvalue" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration" + else + l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration" + fi + if [ -n "$l_pafile" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\"" + else + l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file" + fi + [ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\"" + } + for l_kpe in $l_parlist; do + l_kpname="$(awk -F= '{print $1}' <<< "$l_kpe")" + l_kpvalue="$(awk -F= '{print $2}' <<< "$l_kpe")" + KPC + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} +'@ + $script = bash -c $script_string + if ($script -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.6.1.1" + Task = "Ensure SELinux is installed" + Test = { + $result = rpm -q libselinux + if ($result -match "libselinux-") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.6.1.2" + Task = "Ensure SELinux is not disabled in bootloader configuration" + Test = { + $result = grubby --info=ALL | grep -Po '(selinux|enforcing)=0\b' + if ($result -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.6.1.3" + Task = "Ensure SELinux policy is configured" + Test = { + $result1 = grep -E '^\s*SELINUXTYPE=(targeted|mls)\b' /etc/selinux/config + $result2 = sestatus | grep Loaded + if (($result1 -match "targeted" -or $result1 -match "mls") -and ($result2 -match "targeted" -or $result2 -match "mls")) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.6.1.4" + Task = "Ensure the SELinux mode is not disabled" + Test = { + $result1 = getenforce + $result2 = grep -Ei '^\s*SELINUX=(enforcing|permissive)' /etc/selinux/config + if (($result1 -match "Enforcing" -or $result1 -match "Permissive") -and ($result2 -match "SELINUX=enforcing" -or $result2 -match "SELINUX=permissive")) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.6.1.5" + Task = "Ensure the SELinux mode is enforcing" + Test = { + $result1 = getenforce + $result2 = grep -i SELINUX=enforcing /etc/selinux/config + if ($result1 -match "Enforcing" -and $result2 -match "SELINUX=enforcing") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.6.1.6" + Task = "Ensure no uncofined services exist" + Test = { + $result = ps -eZ | grep unconfined_service_t + if ($result -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.6.1.7" + Task = "Ensure SETroubleshoot is not installed" + Test = { + $result = rpm -q setroubleshoot + if ($result -match "is not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.6.1.8" + Task = "Ensure the MCS Translation Service (mcstrans) is not installed" + Test = { + $result = rpm -q mcstrans + if ($result -match "is not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.7.1" + Task = "Ensure the MCS Translation Service (mcstrans) is not installed" + Test = { + $result = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/motd + if ($result -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.7.2" + Task = "Ensure local login warning banner is configured properly" + Test = { + $result = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue + if ($result -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.7.3" + Task = "Ensure remote login warning banner is configured properly" + Test = { + $result = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue.net + if ($result -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.7.4" + Task = "Ensure permissions on /etc/motd are configured" + Test = { + $result = stat -c "%a" /etc/motd + if ($result -eq 644) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.7.5" + Task = "Ensure permissions on /etc/issue are configured" + Test = { + $result = stat -c "%a" /etc/issue + if ($result -eq 644) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.7.6" + Task = "Ensure permissions on /etc/issue.net are configured" + Test = { + $result = stat -c "%a" /etc/issue.net + if ($result -eq 644) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.1" + Task = "Ensure GNOME Display Manager is removed" + Test = { + $result = rpm -q gdm + if ($result -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.2" + Task = "Ensure GDM login banner is configured" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_182.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.3" + Task = "Ensure GDM disable-user-list option is enabled" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_183.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.4" + Task = "Ensure GDM screen locks then the user is idle" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_184.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.5" + Task = "Ensure GDM screen locks cannot be overridden" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_185.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.6" + Task = "Ensure GDM automatic mounting of removable media is disabled" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_186.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.7" + Task = "Ensure GDM disabling automatic mounting of removable media is not overridden" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_187.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.8" + Task = "Ensure GDM autorun-never is enabled" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_188.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.9" + Task = "Ensure GDM autorun-never is not overridden" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_189.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.10" + Task = "Ensure XDCMP is not enabled" + Test = { + $test = grep -Eis '^\s*Enable\s*=\s*true' /etc/gdm/custom.conf + if ($test -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.9" + Task = "Ensure updates, patches, and additional security software are installed" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "1.10" + Task = "Ensure system-wide crypto policy is not legacy" + Test = { + $test = grep -E -i '^\s*LEGACY\s*(\s+#.*)?$' /etc/crypto-policies/config + if ($test -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + + +### Chapter 2 - Services + + +[AuditTest] @{ + Id = "2.1.1" + Task = "Ensure time synchronization is in use" + Test = { + $test = rpm -q chrony + if ($test -match "chrony-") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.1.2" + Task = "Ensure chrony is configured" + Test = { + $test = grep -E "^(server|pool)" /etc/chrony.conf | grep OPTIONS\s*-u\s*chrony + if ($test -match "OPTIONS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.1" + Task = "Ensure xorg-x11-server-common is not installed" + Test = { + $test = rpm -q xorg-x11-server-common + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.2" + Task = "Ensure Avahi Server is not installed" + Test = { + $test = rpm -q avahi + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.3" + Task = "Ensure CUPS is not installed" + Test = { + $test = rpm -q cups + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.4" + Task = "Ensure DHCP Server is not installed" + Test = { + $test = rpm -q dhcp-server + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.5" + Task = "Ensure DNS Server is not installed" + Test = { + $test = rpm -q bind + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.6" + Task = "Ensure VSFTP Server is not installed" + Test = { + $test = rpm -q vsftpd + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.7" + Task = "Ensure VSFTP Server is not installed" + Test = { + $test = rpm -q vsftpd + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.8" + Task = "Ensure a web server is not installed" + Test = { + $test = rpm -q httpd nginx + if ($test -match "httpd is not installed" -and $test -match "nginx is not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.9" + Task = "Ensure IMAP and POP3 server is not installed" + Test = { + $test = rpm -q dovecot cyrus-imapd + if ($test -match "dovecot is not installed" -and $test -match "cyrus-imapd is not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.10" + Task = "Ensure Samba is not installed" + Test = { + $test = rpm -q samba + if ($test -match "samba is not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.11" + Task = "Ensure HTTP Proxy Server is not installed" + Test = { + $test = rpm -q squid + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.12" + Task = "Ensure net-snmp is not installed" + Test = { + $test = rpm -q net-snmp + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.13" + Task = "Ensure telnet-server is not installed" + Test = { + $test = rpm -q telnet-server + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.14" + Task = "Ensure dnsmasq is not installed" + Test = { + $test = rpm -q dnsmasq + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.15" + Task = "Ensure mail transfer agent is configured for local-only mode" + Test = { + $test = ss -lntu | grep -E ':25\s' | grep -E -v '\s(127.0.0.1|\[?::1\]?):25\s' + if ($test -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.16" + Task = "Ensure nfs-utils is not installed or the nfs-server service is masked" + Test = { + rpm -q nfs-utils + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.17" + Task = "Ensure rpcbind is not installed or the rpcbind services are masked" + Test = { + $test1 = rpm -q rpcbind + $test21 = systemctl is-enabled rpcbind + $test22 = systemctl is-enabled rpcbind.socket + if ($test1 -match "not installed" -or ($test21 -match "masked" -and $test22 -match "masked")) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.18" + Task = "Ensure rsync-daemon is not installed or the rsyncd service is masked" + Test = { + $test1 = rpm -q rsync-daemon + $test2 = systemctl is-enabled rsync-daemon + if ($test1 -match "not installed" -or $test2 -match "masked") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.3.1" + Task = "Ensure telnet client is not installed" + Test = { + $test = rpm -q telnet + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.3.2" + Task = "Ensure LDAP client is not installed" + Test = { + $test = rpm -q openldap-clients + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.3.3" + Task = "Ensure TFTP client is not installed" + Test = { + $test = rpm -q tftp + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.3.4" + Task = "Ensure FTP client is not installed" + Test = { + $test = rpm -q ftp + if ($test -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.4" + Task = "Ensure nonessential services listening on the system are removed or masked" + Test = { + return $retNonCompliantManualReviewRequired + } +} + + +### Chapter 3 - Network Configuration + + +[AuditTest] @{ + Id = "3.1.1" + Task = "Ensure IPv6 status is identified" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "3.1.2" + Task = "Ensure wireless interfaces are disabled" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_312.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.1.3" + Task = "Ensure TIPC is disabled" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_313.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.2.1" + Task = "Ensure IP forwarding is disabled" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_321.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.2.2" + Task = "Ensure packet redirect sending is disabled" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_322_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_322_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "PASS" -and $result2 -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.1" + Task = "Ensure packet redirect sending is disabled" + Test = { + $resultScript11 = $scriptPath + "CIS100_RHEL9_331_11.sh" + $result11 = bash $resultScript11 + $resultScript12 = $scriptPath + "CIS100_RHEL9_331_12.sh" + $result12 = bash $resultScript12 + $resultScript21 = $scriptPath + "CIS100_RHEL9_331_21.sh" + $result21 = bash $resultScript21 + $resultScript22 = $scriptPath + "CIS100_RHEL9_331_22.sh" + $result22 = bash $resultScript22 + if ($IPv6Status -eq "enabled") { + if ($result21 -match "PASS" -and $result22 -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } else { + if ($result11 -match "PASS" -and $result12 -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } + } +} + +[AuditTest] @{ + Id = "3.3.2" + Task = "Ensure ICMP redirects are not accepted" + Test = { + $resultScript11 = $scriptPath + "CIS100_RHEL9_332_11.sh" + $result11 = bash $resultScript11 + $resultScript12 = $scriptPath + "CIS100_RHEL9_332_12.sh" + $result12 = bash $resultScript12 + $resultScript21 = $scriptPath + "CIS100_RHEL9_332_21.sh" + $result21 = bash $resultScript21 + $resultScript22 = $scriptPath + "CIS100_RHEL9_332_22.sh" + $result22 = bash $resultScript22 + if ($IPv6Status -eq "enabled") { + if ($result21 -match "PASS" -and $result22 -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } else { + if ($result11 -match "PASS" -and $result12 -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } + } +} + +# 3.3.3 ist identisch mit 3.3.2 ... warum auch immer - wird hier weg gelassen + +[AuditTest] @{ + Id = "3.3.4" + Task = "Ensure suspicious packets are logged" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_334_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_334_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "PASS" -and $result2 -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.5" + Task = "Ensure broadcast ICMP requests are ignored" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_335.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.6" + Task = "Ensure bogus ICMP responses are ignored" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_336.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.7" + Task = "Ensure Reverse Path Filtering is enabled" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_337_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_337_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "PASS" -and $result2 -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.8" + Task = "Ensure TCP SYN Cookies is enabled" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_338.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.9" + Task = "Ensure IPv6 router advertisements are not accepted" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_339_1.sh" + $resultScript1 = $scriptPath + "CIS100_RHEL9_339_2.sh" + if ($IPv6Status -match "disabled") { + return $retCompliantIPv6Disabled + } else { + $script1 = bash $resultScript1 + $script2 = bash $resultScript2 + if ($script1 -match "PASS" -and $script2 -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } + } +} + +[AuditTest] @{ + Id = "3.4.1.1" + Task = "Ensure nftables is installed" + Test = { + $result = rpm -q nftables + if ($result -match "nftables-") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.4.1.2" + Task = "Ensure a single firewall configuration utility is in use" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_3412.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.4.2.1" + Task = "Ensure firewalld default zone is set" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_3421.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.4.2.2" + Task = "Ensure at least one nftables table exists" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "3.4.2.3" + Task = "Ensure nftables base chains exist" + Test = { + try{ + $test1 = nft list ruleset | grep 'hook input' + $test2 = nft list ruleset | grep 'hook forward' + $test3 = nft list ruleset | grep 'hook output' + if($test1 -match "type filter hook input" -and $test2 -match "type filter hook forward" -and $test3 -match "type filter hook output"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} + +[AuditTest] @{ + Id = "3.4.2.4" + Task = "Ensure host based firewall loopback traffic is configured" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + l_output="" l_output2="" + if nft list ruleset | awk '/hook\s+input\s+/,/\}\s*(#.*)?$/' | grep -Pq -- '\H+\h+"lo"\h+accept'; then + l_output="$l_output\n - Network traffic to the loopback address is correctly set to accept" + else + l_output2="$l_output2\n - Network traffic to the loopback address is not set to accept" + fi + l_ipsaddr="$(nft list ruleset | awk '/filter_IN_public_deny|hook\s+input\s+/,/\}\s*(#.*)?$/' | grep -P -- 'ip\h+saddr')" + if grep -Pq -- 'ip\h+saddr\h+127\.0\.0\.0\/8\h+(counter\h+packets\h+\d+\h+bytes\h+\d+\h+)?drop' <<< "$l_ipsaddr" || grep -Pq -- 'ip\h+daddr\h+\!\=\h+127\.0\.0\.1\h+ip\h+saddr\h+127\.0\.0\.1\h+drop' <<< "$l_ipsaddr"; then + l_output="$l_output\n - IPv4 network traffic from loopback address correctly set to drop" + else + l_output2="$l_output2\n - IPv4 network traffic from loopback address not set to drop" + fi + if grep -Pq -- '^\h*0\h*$' /sys/module/ipv6/parameters/disable; then + l_ip6saddr="$(nft list ruleset | awk '/filter_IN_public_deny|hook input/,/}/' | grep 'ip6 saddr')" + if grep -Pq 'ip6\h+saddr\h+::1\h+(counter\h+packets\h+\d+\h+bytes\h+\d+\h+)?drop' <<< "$l_ip6saddr" || grep -Pq -- 'ip6\h+daddr\h+\!=\h+::1\h+ip6\h+saddr\h+::1\h+drop' <<< "$l_ip6saddr"; then + l_output="$l_output\n - IPv6 network traffic from loopback address correctly set to drop" + else + l_output2="$l_output2\n - IPv6 network traffic from loopback address not set to drop" + fi + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output" + else + echo -e "\n- Audit Result:\n FAIL\n$l_output2\n\n - Correctly set:\n$l_output" + fi +} +'@ + $script = bash -c $script_string + if ($script -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.4.2.5" + Task = "Ensure firewalld drops unnecessary services and ports" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "3.4.2.6" + Task = "Ensure nftables established connections are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "3.4.2.7" + Task = "Ensure nftables default deny firewall policy" + Test = { + $result1 = systemctl --quiet is-enabled nftables.service && nft list ruleset | grep 'hook input' | grep -v 'policy drop' + $result2 = systemctl --quiet is-enabled nftables.service && nft list ruleset | grep 'hook forward' | grep -v 'policy drop' + if ($result1 -eq $null -and $result2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + + +### Chapter 4 - Logging and Auditing + + +[AuditTest] @{ + Id = "4.1.1.1" + Task = "Ensure auditd is installed" + Test = { + $result1 = rpm -q audit + if ($result1 -match "audit-") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.1.2" + Task = "Ensure auditing for processes that start prior to auditd is enabled" + Test = { + $result1 = grubby --info=ALL | grep -Po '\baudit=1\b' + if ($result1 -match "audit=1") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.1.3" + Task = "Ensure audit_backlog_limit is sufficient" + Test = { + $result1 = grubby --info=ALL | grep -Po "\baudit_backlog_limit=\d+\b" + if ($result1 -match "audit_backlog_limit=") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.1.4" + Task = "Ensure auditd service is enabled" + Test = { + $result1 = systemctl is-enabled auditd + if ($result1 -match "enabled") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.2.1" + Task = "Ensure audit log storage size is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "4.1.2.2" + Task = "Ensure audit logs are not automatically deleted" + Test = { + $result1 = grep max_log_file_action /etc/audit/auditd.conf | grep max_log_file_action + if ($result1 -match "max_log_file_action = keep_logs") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.2.3" + Task = "Ensure system is disabled when audit logs are full" + Test = { + $result1 = grep space_left_action /etc/audit/auditd.conf + $result2 = grep action_mail_acct /etc/audit/auditd.conf + $result3 = grep -E 'admin_space_left_action\s*=\s*(halt|single)' /etc/audit/auditd.conf + if ($result1 -match "space_left_action = email" -and $result2 -match "action_mail_acct = root" -and ($result3 -match "admin_space_left_action = halt" -or $result3 -match "admin_space_left_action = single")) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.1" + Task = "Ensure changes to system administration scope (sudoers) is collected" + Test = { + $result1 = awk '/^ *-w/ &&/\/etc\/sudoers/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules + $result2 = auditctl -l | awk '/^ *-w/ &&/\/etc\/sudoers/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' + if ($result1 -match "-w /etc/sudoers -p wa -k scope" -and $result1 -match "-w /etc/sudoers.d -p wa -k scope" -and $result2 -match "-w /etc/sudoers -p wa -k scope" -and $result2 -match "-w /etc/sudoers.d -p wa -k scope") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.2" + Task = "Ensure actions as another user are always logged" + Test = { + $result1 = awk '/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&(/ -C *euid!=uid/||/ -C *uid!=euid/) &&/ -S *execve/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules + $result2 = auditctl -l | awk '/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&(/ -C *euid!=uid/||/ -C *uid!=euid/) &&/ -S *execve/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' + if ($result1 -match "-a always,exit -F arch=b64 -C euid!=uid -F auid!=unset -S execve -k user_emulation" -and $result1 -match "-a always,exit -F arch=b32 -C euid!=uid -F auid!=unset -S execve -k user_emulation" -and $result2 -match "-a always,exit -F arch=b64 -S execve -C uid!=euid -F auid!=-1 -F key=user_emulation" -and $result2 -match "-a always,exit -F arch=b32 -S execve -C uid!=euid -F auid!=-1 -F key=user_emulation") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.3" + Task = "Ensure events that modify the sudo log file are collected" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_4133_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_4133_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "-w /var/log/sudo.log -p wa -k sudo_log_file" -and $result2 -match "-w /var/log/sudo.log -p wa -k sudo_log_file") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.4" + Task = "Ensure events that modify date and time information are collected" + Test = { + $script_string1 = @' + #!/usr/bin/env bash + { + awk '/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&/ -S/ &&(/adjtimex/ ||/settimeofday/ ||/clock_settime/ ) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules + awk '/^ *-w/ &&/\/etc\/localtime/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules + } +'@ + $script_string2 = @' +#!/usr/bin/env bash +{ + auditctl -l | awk '/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&/ -S/ &&(/adjtimex/ ||/settimeofday/ ||/clock_settime/ ) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' + auditctl -l | awk '/^ *-w/ &&/\/etc\/localtime/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' +} +'@ + $result1 = bash -c $script_string1 + $result2 = bash -c $script_string2 + if ($result1 -match "-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -F key=time-change" -and $result1 -match "-a always,exit -F arch=b32 -S adjtimex,settimeofday,clock_settime -k time-change" -and $result1 -match "-w /etc/localtime -p wa -k time-change" -and + $result2 -match "-w /var/log/sudo.log -p wa -k sudo_log_file" -and $result2 -match "-a always,exit -F arch=b32 -S adjtimex,settimeofday,clock_settime -F key=time-change" -and $result2 -match "-w /etc/localtime -p wa -k time-change") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.5" + Task = "Ensure events that modify the system's network environment are collected" + Test = { + $script_string1 = @' + #!/usr/bin/env bash + { + awk '/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&/ -S/ &&(/sethostname/ ||/setdomainname/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules + awk '/^ *-w/ &&(/\/etc\/issue/ ||/\/etc\/issue.net/ ||/\/etc\/hosts/ ||/\/etc\/sysconfig\/network/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules + } +'@ + $script_string2 = @' +#!/usr/bin/env bash +{ + auditctl -l | awk '/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&/ -S/ &&(/sethostname/ ||/setdomainname/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' + auditctl -l | awk '/^ *-w/ &&(/\/etc\/issue/ ||/\/etc\/issue.net/ ||/\/etc\/hosts/ ||/\/etc\/sysconfig\/network/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' +} +'@ + $result1 = bash -c $script_string1 + $result2 = bash -c $script_string2 + if ($result1 -match "-a always,exit -F arch=b64 -S sethostname,setdomainname -k system-locale" -and $result1 -match "-a always,exit -F arch=b32 -S sethostname,setdomainname -k system-locale" -and $result1 -match "-w /etc/issue -p wa -k system-locale" -and $result1 -match "-w /etc/issue.net -p wa -k system-locale" -and $result1 -match "-w /etc/hosts -p wa -k system-locale" -and $result1 -match "-w /etc/sysconfig/network -p wa -k system-locale" -and $result1 -match "-w /etc/sysconfig/network-scripts/ -p wa -k system-locale" -and + $result2 -match "-a always,exit -F arch=b64 -S sethostname,setdomainname -F key=system-locale" -and $result2 -match "-a always,exit -F arch=b32 -S sethostname,setdomainname -F key=system-locale" -and $result2 -match "-w /etc/issue -p wa -k system-locale" -and $result2 -match "-w /etc/issue.net -p wa -k system-locale" -and $result2 -match "-w /etc/hosts -p wa -k system-locale" -and $result2 -match "-w /etc/sysconfig/network -p wa -k system-locale" -and $result2 -match "-w /etc/sysconfig/network-scripts -p wa -k system-locale") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.6" + Task = "Ensure use of privileged commands are collected" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_4136_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_4136_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "Warning" -or $result2 -match "Warning") { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.7" + Task = "Ensure unsuccessful file access attempts are collected" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_4137_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_4137_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "-a always,exit -F arch=b64 -S creat,open,openat,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -k access" -and $result1 -match "-a always,exit -F arch=b64 -S creat,open,openat,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -k access" -and $result1 -match "-a always,exit -F arch=b32 -S creat,open,openat,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -k access" -and $result1 -match "-a always,exit -F arch=b32 -S creat,open,openat,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -k access" -and + $result2 -match "-a always,exit -F arch=b64 -S open,truncate,ftruncate,creat,openat -F exit=-EACCES -F auid>=1000 -F auid!=-1 -F key=access" -and $result2 -match "-a always,exit -F arch=b64 -S open,truncate,ftruncate,creat,openat -F exit=-EPERM -F auid>=1000 -F auid!=-1 -F key=access" -and $result2 -match "-a always,exit -F arch=b32 -S open,truncate,ftruncate,creat,openat -F exit=-EACCES -F auid>=1000 -F auid!=-1 -F key=access" -and $result2 -match "-a always,exit -F arch=b32 -S open,truncate,ftruncate,creat,openat -F exit=-EPERM -F auid>=1000 -F auid!=-1 -F key=access") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.8" + Task = "Ensure events that modify user/group information are collected" + Test = { + $script_string1 = @' +#!/usr/bin/env bash +{ + awk '/^ *-w/ &&(/\/etc\/group/ ||/\/etc\/passwd/ ||/\/etc\/gshadow/ ||/\/etc\/shadow/ ||/\/etc\/security\/opasswd/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules +} +'@ + $script_string2 = @' +#!/usr/bin/env bash +{ + auditctl -l | awk '/^ *-w/ &&(/\/etc\/group/ ||/\/etc\/passwd/ ||/\/etc\/gshadow/ ||/\/etc\/shadow/ ||/\/etc\/security\/opasswd/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' +} +'@ + $result1 = bash -c $script_string1 + $result2 = bash -c $script_string2 + if ($result1 -match "-w /etc/group -p wa -k identity" -and $result1 -match "-w /etc/passwd -p wa -k identity" -and $result1 -match "-w /etc/gshadow -p wa -k identity" -and $result1 -match "-w /etc/shadow -p wa -k identity" -and $result1 -match "-w /etc/security/opasswd -p wa -k identity" -and + $result2 -match "-w /etc/group -p wa -k identity" -and $result2 -match "-w /etc/passwd -p wa -k identity" -and $result2 -match "-w /etc/gshadow -p wa -k identity" -and $result2 -match "-w /etc/shadow -p wa -k identity" -and $restul2 -match "-w /etc/security/opasswd -p wa -k identity") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.9" + Task = "Ensure discretionary access control permission modification events are collected" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_4139_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_4139_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod" -and $result1 -match "-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod" -and $result1 -match "-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod" -and + $result1 -match "-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod" -and $result1 -match "-a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod" -and $result1 -match "-a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod" -and + $result2 -match "-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and $result2 -match "-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and $result2 -match "-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and + $result2 -match "-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and $result2 -match "-a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and $result2 -match "-a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=-1 -F key=perm_mod") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.10" + Task = "Ensure successful file system mounts are collected" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_41310_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_41310_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=unset -k mounts" -and $result1 -match "-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=unset -k mounts" -and + $result2 -match "-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=-1 -F key=mounts" -and $result2 -match "-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=-1 -F key=mounts") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.11" + Task = "Ensure session initiation information is collected" + Test = { + $script_string1 = @' +#!/usr/bin/env bash +{ + awk '/^ *-w/ &&(/\/var\/run\/utmp/ ||/\/var\/log\/wtmp/ ||/\/var\/log\/btmp/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules +} +'@ + $script_string2 = @' +#!/usr/bin/env bash +{ + auditctl -l | awk '/^ *-w/ &&(/\/var\/run\/utmp/ ||/\/var\/log\/wtmp/ ||/\/var\/log\/btmp/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' +} +'@ + $result1 = bash -c $script_string1 + $result2 = bash -c $script_string2 + if ($result1 -match "-w /var/run/utmp -p wa -k session" -and $result1 -match "-w /var/log/wtmp -p wa -k session" -and $result1 -match "-w /var/log/btmp -p wa -k session" -and + $result2 -match "-w /var/run/utmp -p wa -k session" -and $result2 -match "-w /var/log/wtmp -p wa -k session" -and $result2 -match "-w /var/log/btmp -p wa -k session") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "4.1.3.12" + Task = "Ensure login and logout events are collected" + Test = { + $script_string1 = @' +#!/usr/bin/env bash +{ + awk '/^ *-w/ \ + &&(/\/var\/log\/lastlog/ \ + ||/\/var\/run\/faillock/) \ + &&/ +-p *wa/ \ + &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules +} +'@ + $script_string2 = @' +#!/usr/bin/env bash +{ + auditctl -l | awk '/^ *-w/ \ + &&(/\/var\/log\/lastlog/ \ + ||/\/var\/run\/faillock/) \ + &&/ +-p *wa/ \ + &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' +} +'@ + $result1 = bash -c $script_string1 + $result2 = bash -c $script_string2 + if ($result1 -match "-w /var/log/lastlog -p wa -k logins" -and $result1 -match "-w /var/run/faillock -p wa -k logins" -and + $result2 -match "-w /var/log/lastlog -p wa -k logins" -and $result2 -match "-w /var/run/faillock -p wa -k logins") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.13" + Task = "Ensure file deletion events by users are collected" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_41313_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_41313_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F auid>=1000 -F auid!=unset -k delete" -and $result1 -match "-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F auid>=1000 -F auid!=unset -k delete" -and + $result2 -match "-a always,exit -F arch=b64 -S rename,unlink,unlinkat,renameat -F auid>=1000 -F auid!=-1 -F key=delete" -and $result2 -match "-a always,exit -F arch=b32 -S unlink,rename,unlinkat,renameat -F auid>=1000 -F auid!=-1 -F key=delete") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.14" + Task = "Ensure events that modify the system's Mandatory Access Controls are collected" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_41314_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_41314_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "-w /etc/selinux -p wa -k MAC-policy" -and $result1 -match "-w /usr/share/selinux -p wa -k MAC-policy" -and + $result2 -match "-w /etc/selinux -p wa -k MAC-policy" -and $result2 -match "-w /usr/share/selinux -p wa -k MAC-policy") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.15" + Task = "Ensure successful and unsuccessful attempts to use the chcon command are recorded" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_41315_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_41315_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "-a always,exit -F path=/usr/bin/chcon -F perm=x -F auid>=1000 -F auid!=unset -k perm_chng" -and + $result2 -match "-a always,exit -S all -F path=/usr/bin/chcon -F perm=x -F auid>=1000 -F auid!=-1 -F key=perm_chng") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.16" + Task = "Ensure successful and unsuccessful attempts to use the setfacl command are recorded" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_41316_1.sh" + $resultScript2 = $scriptPath + "CIS100_RHEL9_41316_2.sh" + $result1 = bash $resultScript1 + $result2 = bash $resultScript2 + if ($result1 -match "-a always,exit -F path=/usr/bin/setfacl -F perm=x -F auid>=1000 -F auid!=unset -k perm_chng" -and + $result2 -match "-a always,exit -S all -F path=/usr/bin/setfacl -F perm=x -F auid>=1000 -F auid!=-1 -F key=perm_chng") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.17" + Task = "Ensure successful and unsuccessful attempts to use the chacl command are recorded" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_41317_1.sh" + $resultScript2 = $scriptPath + "CIS100_RHEL9_41317_2.sh" + $result1 = bash $resultScript1 + $result2 = bash $resultScript2 + if ($result1 -match "-a always,exit -F path=/usr/bin/chacl -F perm=x -F auid>=1000 -F auid!=unset -k perm_chng" -and + $result2 -match "-a always,exit -S all -F path=/usr/bin/chacl -F perm=x -F auid>=1000 -F auid!=-1 -F key=perm_chng") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.18" + Task = "Ensure successful and unsuccessful attempts to use the usermod command are recorded" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_41318_1.sh" + $resultScript2 = $scriptPath + "CIS100_RHEL9_41318_2.sh" + $result1 = bash $resultScript1 + $result2 = bash $resultScript2 + if ($result1 -match "-a always,exit -F path=/usr/sbin/usermod -F perm=x -F auid>=1000 -F auid!=unset -k usermod" -and + $result2 -match "-a always,exit -S all -F path=/usr/sbin/usermod -F perm=x -F auid>=1000 -F auid!=-1 -F key=usermod") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.19" + Task = "Ensure kernel module loading unloading and modification is collected" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_41319_1.sh" + $resultScript2 = $scriptPath + "CIS100_RHEL9_41319_2.sh" + $result1 = bash $resultScript1 + $result2 = bash $resultScript2 + if ($result1 -match "-a always,exit -F arch=b64 -S init_module,finit_module,delete_module,create_module,query_module -F auid>=1000 -F auid!=unset -k kernel_modules" -and $result1 -match "-a always,exit -F path=/usr/bin/kmod -F perm=x -F auid>=1000 -F auid!=unset -k kernel_modules" -and + $result2 -match "-a always,exit -F arch=b64 -S create_module,init_module,delete_module,query_module,finit_module -F auid>=1000 -F auid!=-1 -F key=kernel_modules" -and $result2 -match "-a always,exit -S all -F path=/usr/bin/kmod -F perm=x -F auid>=1000 -F auid!=-1 -F key=kernel_modules" -and $result3 -match "OK") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.20" + Task = "Ensure the audit configuration is immutable" + Test = { + $result1 = grep -Ph -- '^\h*-e\h+2\b' /etc/audit/rules.d/*.rules | tail -1 + if ($result1 -match "-e 2") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.3.21" + Task = "Ensure the running and on disk configuration is the same" + Test = { + $result1 = augenrules --check + if ($result1 -match "/usr/sbin/augenrules: No change") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.4.1" + Task = "Ensure audit log files are mode 0640 or less permissive" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_4141.sh" + $result = bash $resultScript + if ($result -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.4.2" + Task = "Ensure only authorized users own audit log files" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_3412.sh" + $result = bash $resultScript + if ($result -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.4.3" + Task = "Ensure only authorized groups are assigned ownership of audit log files" + Test = { + $script_string1 = @' +#!/usr/bin/env bash +{ + stat -c "%n %G" "$(dirname $(awk -F"=" '/^\s*log_file\s*=\s*/ {print $2}' /etc/audit/auditd.conf | xargs))"/* | grep -Pv '^\h*\H+\h+(adm|root)\b' +} +'@ + $result1 = bash -c $script_string1 + $result2 = grep -Piw -- '^\h*log_group\h*=\h*(adm|root)\b' /etc/audit/auditd.conf + if (($result1 -match "log_group = adm" -or $result1 -match "log_group = root") -and $result2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.4.4" + Task = "Ensure the audit log directory is 0750 or more restrictive" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_4144.sh" + $result = bash $resultScript + if ($result -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.4.5" + Task = "Ensure audit configuration files are 640 or more restrictive" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_4145.sh" + $result = bash $resultScript + if ($result -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.4.6" + Task = "Ensure audit configuration files are owned by root" + Test = { + $result1_string = @' +#!/usr/bin/env bash +{ + find /etc/audit/ -type f \( -name '*.conf' -o -name '*.rules' \) ! -user root +} +'@ + $result1 = bash -c $result1_string + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.4.7" + Task = "Ensure audit configuration files belong to group root" + Test = { + $result1_string = @' +#!/usr/bin/env bash +{ + find /etc/audit/ -type f \( -name '*.conf' -o -name '*.rules' \) ! -group root +} +'@ + $result1 = bash -c $result1_string + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.4.8" + Task = "Ensure audit tools are 755 or more restrictive" + Test = { + $result1 = stat -c "%n %a" /sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules | grep -Pv -- '^\h*\H+\h+([0-7][0,1,4,5][0,1,4,5])\h*$' + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.4.9" + Task = "Ensure audit tools are owned by root" + Test = { + $result1 = stat -c "%n %U" /sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules | grep -Pv -- '^\h*\H+\h+root\h*$' + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.4.10" + Task = "Ensure audit tools belong to group root" + Test = { + $result1 = stat -c "%n %a %U %G" /sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules | grep -Pv -- '^\h*\H+\h+([0-7][0,1,4,5][0,1,4,5])\h+root\h+root\h*$' + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.1.1" + Task = "Ensure rsyslog is installed" + Test = { + $result1 = rpm -q rsyslog + if ($result1 -match "rsyslog-") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.1.2" + Task = "Ensure rsyslog service is enabled" + Test = { + $result1 = systemctl is-enabled rsyslog + if ($result1 -match "enabled") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.1.3" + Task = "Ensure journald is configured to send logs to rsyslog" + Test = { + $result1 = grep ^\s*ForwardToSyslog /etc/systemd/journald.conf + if ($result1 -match "ForwardToSyslog=yes") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.1.4" + Task = "Ensure journald is configured to send logs to rsyslog" + Test = { + $result1 = grep -Ps '^\h*\$FileCreateMode\h+0[0,2,4,6][0,2,4]0\b' /etc/rsyslog.conf /etc/rsyslog.d/*.conf + if ($result1 -match "FileCreateMode 0640") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.1.5" + Task = "Ensure logging is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "4.2.1.6" + Task = "Ensure rsyslog is configured to send logs to a remote log host" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "4.2.1.7" + Task = "Ensure journald is configured to send logs to rsyslog" + Test = { + $result1 = grep -Ps -- '^\h*module\(load="imtcp"\)' /etc/rsyslog.conf /etc/rsyslog.d/*.conf + $result2 = grep -Ps -- '^\h*input\(type="imtcp" port="514"\)' /etc/rsyslog.conf /etc/rsyslog.d/*.conf + if ($result1 -eq $null -and $result2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.2.1.1" + Task = "Ensure journald is configured to send logs to rsyslog" + Test = { + $result1 = rpm -q systemd-journal-remote + if ($result1 -eq "systemd-journal-remote-") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.2.1.2" + Task = "Ensure systemd-journal-remote is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "4.2.2.1.3" + Task = "Ensure systemd-journal-remote is enabled" + Test = { + $result1 = systemctl is-enabled systemd-journal-upload.service + if ($result1 -match "enabled") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.2.1.4" + Task = "Ensure journald is not configured to receive logs from a remote client" + Test = { + $result1 = systemctl is-enabled systemd-journal-remote.socket + if ($result1 -match "masked") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.2.2" + Task = "Ensure journald service is enabled" + Test = { + $result1 = systemctl is-enabled systemd-journald.service + if ($result1 -match "static") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.2.3" + Task = "Ensure journald is configured to compress large log files" + Test = { + $result1 = grep ^\s*Compress /etc/systemd/journald.conf + if ($result1 -match "Compress=yes") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.2.4" + Task = "Ensure journald is configured to write logfiles to persistent disk" + Test = { + $result1 = grep ^\s*Storage /etc/systemd/journald.conf + if ($result1 -match "Storage=persistent") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.2.5" + Task = "Ensure journald is not configured to send logs to rsyslog" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "4.2.2.6" + Task = "Ensure journald log rotation is configured per site policy" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "4.2.2.7" + Task = "Ensure journald default file permissions configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "4.2.3" + Task = "Ensure all logfiles have appropriate permissions and ownership" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + echo -e "\n- Start check - logfiles have appropriate permissions and ownership" + output="" + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + find /var/log -type f | (while read -r fname; do + bname="$(basename "$fname")" + fugname="$(stat -Lc "%U %G" "$fname")" + funame="$(awk '{print $1}' <<< "$fugname")" + fugroup="$(awk '{print $2}' <<< "$fugname")" + fuid="$(stat -Lc "%u" "$fname")" + fmode="$(stat -Lc "%a" "$fname")" + case "$bname" in lastlog | lastlog.* | wtmp | wtmp.* | wtmp-* | btmp | btmp.* | btmp-*) + if ! grep -Pq -- '^\h*[0,2,4,6][0,2,4,6][0,4]\h*$' <<< "$fmode"; then + output="$output\n- File: \"$fname\" mode: \"$fmode\"\n" + fi + if ! grep -Pq -- '^\h*root\h+(utmp|root)\h*$' <<< "$fugname"; then + output="$output\n- File: \"$fname\" ownership: \"$fugname\"\n" + fi + ;; + secure | auth.log | syslog | messages) + if ! grep -Pq -- '^\h*[0,2,4,6][0,4]0\h*$' <<< "$fmode"; then + output="$output\n- File: \"$fname\" mode: \"$fmode\"\n" + fi + if ! grep -Pq -- '^\h*(syslog|root)\h+(adm|root)\h*$' <<< "$fugname"; then + output="$output\n- File: \"$fname\" ownership: \"$fugname\"\n" + fi + ;; + SSSD | sssd) + if ! grep -Pq -- '^\h*[0,2,4,6][0,2,4,6]0\h*$' <<< "$fmode"; then + output="$output\n- File: \"$fname\" mode: \"$fmode\"\n" + fi + if ! grep -Piq -- '^\h*(SSSD|root)\h+(SSSD|root)\h*$' <<< "$fugname"; then + output="$output\n- File: \"$fname\" ownership: \"$fugname\"\n" + fi + ;; + gdm | gdm3) + if ! grep -Pq -- '^\h*[0,2,4,6][0,2,4,6]0\h*$' <<< "$fmode"; then + output="$output\n- File: \"$fname\" mode: \"$fmode\"\n" + fi + if ! grep -Pq -- '^\h*(root)\h+(gdm3?|root)\h*$' <<< "$fugname"; then + output="$output\n- File: \"$fname\" ownership: \"$fugname\"\n" + fi + ;; + *.journal | *.journal~) + if ! grep -Pq -- '^\h*[0,2,4,6][0,4]0\h*$' <<< "$fmode"; then + output="$output\n- File: \"$fname\" mode: \"$fmode\"\n" + fi + if ! grep -Pq -- '^\h*(root)\h+(systemd-journal|root)\h*$' <<< "$fugname"; then + output="$output\n- File: \"$fname\" ownership: \"$fugname\"\n" + fi + ;; + *) if ! grep -Pq -- '^\h*[0,2,4,6][0,4]0\h*$' <<< "$fmode"; then + output="$output\n- File: \"$fname\" mode: \"$fmode\"\n" + fi + if [ "$fuid" -ge "$UID_MIN" ] || ! grep -Pq -- '(adm|root|'"$(id -gn "$funame")"')' <<< "$fugroup"; then + if [ -n "$(awk -v grp="$fugroup" -F: '$1==grp {print $4}' /etc/group)" ] || ! grep -Pq '(syslog|root)' <<< "$funame"; then + output="$output\n- File: \"$fname\" ownership: \"$fugname\"\n" + fi + fi + ;; + esac + done # If all files passed, then we pass + if [ -z "$output" ]; then + echo -e "\n- Audit Results:\n PASS\n- All files in \"/var/log/\" have appropriate permissions and ownership\n" + else # print the reason why we are failing + echo -e "\n- Audit Results:\n FAIL\n$output" + fi + echo -e "- End check - logfiles have appropriate permissions and ownership\n" + ) +} +'@ + $script = bash -c $script_string + if ($script -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.3" + Task = "Ensure logrotate is configured" + Test = { + return $retNonCompliantManualReviewRequired + + } +} + + +### Chapter 5 - Access, Authentication and Authorization + + +[AuditTest] @{ + Id = "5.1.1" + Task = "Ensure cron daemon is enabled" + Test = { + $result1 = systemctl is-enabled crond + if ($result1 -match "enabled") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.2" + Task = "Ensure permissions on /etc/crontab are configured" + Test = { + $result1 = stat -c "%a" /etc/crontab + if ($result1 -eq 600 ) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.3" + Task = "Ensure permissions on /etc/cron.hourly are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.hourly + if ($result1 -eq 700 ) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.4" + Task = "Ensure permissions on /etc/cron.daily are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.daily + if ($result1 -eq 700 ) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.5" + Task = "Ensure permissions on /etc/cron.weekly are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.weekly + if ($result1 -eq 700 ) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.6" + Task = "Ensure permissions on /etc/cron.monthly are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.monthly + if ($result1 -eq 700 ) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.7" + Task = "Ensure permissions on /etc/cron.d are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.d + if ($result1 -eq 700 ) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.8" + Task = "Ensure cron is restricted to authorized users" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + if rpm -q cronie >/dev/null; then + [ -e /etc/cron.deny ] && echo "Fail: cron.deny exists" + if [ ! -e /etc/cron.allow ]; then + echo "Fail: cron.allow doesn't exist" + else + ! stat -Lc "%a" /etc/cron.allow | grep -Eq "[0,2,4,6]00" && echo "Fail: cron.allow mode too permissive" + ! stat -Lc "%u:%g" /etc/cron.allow | grep -Eq "^0:0$" && echo "Fail: cron.allow owner and/or group not root" + fi + if [ ! -e /etc/cron.deny ] && [ -e /etc/cron.allow ] && stat -Lc "%a" /etc/cron.allow | grep -Eq "[0,2,4,6]00" \ && stat -Lc "%u:%g" /etc/cron.allow | grep -Eq "^0:0$"; then + echo "Pass" + fi + else + echo "PASS: cron is not installed on the system" + fi +} +'@ + $script = bash -c $script_string + if ($script -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.9" + Task = "Ensure at is restricted to authorized users" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + if rpm -q at >/dev/null; then + [ -e /etc/at.deny ] && echo "Fail: at.deny exists" + if [ ! -e /etc/at.allow ]; then + echo "Fail: at.allow doesn't exist" + else + ! stat -Lc "%a" /etc/at.allow | grep -Eq "[0,2,4,6]00" && echo "Fail: at.allow mode too permissive" + ! stat -Lc "%u:%g" /etc/at.allow | grep -Eq "^0:0$" && echo "Fail: at.allow owner and/or group not root" + fi + if [ ! -e /etc/at.deny ] && [ -e /etc/at.allow ] && stat -Lc "%a" /etc/at.allow | grep -Eq "[0,2,4,6]00" && stat -Lc "%u:%g" /etc/at.allow | grep -Eq "^0:0$"; then + echo "PASS" + fi + else + echo "PASS: at is not installed on the system" + fi +} +'@ + $script = bash -c $script_string + if ($script -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.1" + Task = "Ensure permissions on /etc/ssh/sshd_config are configured" + Test = { + $result1 = stat -Lc "%n %a %u/%U %g/%G" /etc/ssh/sshd_config + if ($result1 -match "/etc/ssh/sshd_config 600 0/root 0/root") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.2" + Task = "Ensure permissions on SSH private host key files are configured" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_522.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.3" + Task = "Ensure permissions on SSH public host key files are configured" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_523.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.4" + Task = "Ensure SSH access is limited" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$' + $test2 = grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$' /etc/ssh/sshd_config + if ($test1 -match "allowusers " -or $test1 -match "allowgroups " -or $test1 -match "denyusers " -or $test1 -match "denygroups " -or + $test2 -match "allowusers " -or $test2 -match "allowgroups " -or $test2 -match "denyusers " -or $test2 -match "denygroups ") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.5" + Task = "Ensure SSH LogLevel is appropriate" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$' + $test2 = grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$' /etc/ssh/sshd_config + if (($test1 -match "allowusers " -or $test1 -match "allowgroups " -or $test1 -match "denyusers " -or $test1 -match "denygroups ") -and + ($test2 -match "allowusers " -or $test2 -match "allowgroups " -or $test2 -match "denyusers " -or $test2 -match "denygroups ")) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.6" + Task = "Ensure SSH PAM is enabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i usepam + $test2 = grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$' /etc/ssh/sshd_config + if ($test1 -match "usepam yes" -and $test2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.7" + Task = "Ensure SSH root login is disabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permitrootlogin + $test2 = grep -Ei '^\s*PermitRootLogin\s+yes' /etc/ssh/sshd_config + if ($test1 -match "permitrootlogin no" -and $test2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.8" + Task = "Ensure SSH HostbasedAuthentication is disabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep hostbasedauthentication + $test2 = grep -Ei '^\s*HostbasedAuthentication\s+yes' /etc/ssh/sshd_config + if ($test1 -match "permitrootlogin no" -and $test2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.9" + Task = "Ensure SSH PermitEmptyPasswords is disabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permitemptypasswords + $test2 = grep -Ei '^\s*PermitEmptyPasswords\s+yes' /etc/ssh/sshd_config + if ($test1 -match "permitemptypasswords no" -and $test2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.10" + Task = "Ensure SSH PermitUserEnvironment is disabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permituserenvironment + $test2 = grep -Ei '^\s*PermitUserEnvironment\s+yes' /etc/ssh/sshd_config + if ($test1 -match "permituserenvironment no" -and $test2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.11" + Task = "Ensure SSH IgnoreRhosts is enabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep ignorerhosts + $test2 = grep -Ei '^\s*ignorerhosts\s+no\b' /etc/ssh/sshd_config + if ($test1 -match "ignorerhosts yes" -and $test2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.12" + Task = "Ensure SSH X11 forwarding is disabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i x11forwarding + $test2 = grep -Ei '^\s*x11forwarding\s+yes' /etc/ssh/sshd_config + if ($test1 -match "x11forwarding no" -and $test2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.13" + Task = "Ensure SSH AllowTcpForwarding is disabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i allowtcpforwarding + $test2 = grep -Ei '^\s*AllowTcpForwarding\s+yes' /etc/ssh/sshd_config + if ($test1 -match "allowtcpforwarding no" -and $test2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.14" + Task = "Ensure system-wide crypto policy is not over-ridden" + Test = { + $test = grep -i '^\s*CRYPTO_POLICY=' /etc/sysconfig/sshd + if ($test -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.15" + Task = "Ensure SSH warning banner is configured" + Test = { + $test = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep banner + if ($test -match "banner /etc/issue.net") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.16" + Task = "Ensure SSH MaxAuthTries is set to 4 or less" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep maxauthtries + $test2 = grep -Ei '^\s*maxauthtries\s+([5-9]|[1-9][0-9]+)' /etc/ssh/sshd_config + if ($test1 -match "maxauthtries 4" -and $test2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.17" + Task = "Ensure SSH MaxStartups is configured" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i maxstartups + $test2 = grep -Ei '^\s*maxstartups\s+(((1[1-9]|[1-9][0-9][0-9]+):([0-9]+):([0-9]+))|(([0-9]+):(3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):([0-9]+))|(([0-9]+):([0-9]+):(6[1-9]|[7-9][0-9]|[1-9][0-9][0-9]+)))' /etc/ssh/sshd_config + if ($test1 -match "maxstartups 10:30:60" -and $test2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.18" + Task = "Ensure SSH MaxSessions is set to 10 or less" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i maxsessions + $test2 = grep -Ei '^\s*MaxSessions\s+(1[1-9]|[2-9][0-9]|[1-9][0-9][0-9]+)' /etc/ssh/sshd_config + if ($test1 -match "maxsessions 10" -and $test2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.19" + Task = "Ensure SSH LoginGraceTime is set to one minute or less" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep logingracetime + $test2 = grep -Ei '^\s*LoginGraceTime\s+(0|6[1-9]|[7-9][0-9]|[1-9][0-9][0-9]+|[^1]m)' /etc/ssh/sshd_config + if ($test1 -match "logingracetime 60" -and $test2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.20" + Task = "Ensure SSH Idle Timeout Interval is configured" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep clientaliveinterval | cut -d ' ' -f 2 + $test2 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep clientalivecountmax | cut -d ' ' -f 2 + if ($test1 -gt 0 -and $test2 -gt 0) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.3.1" + Task = "Ensure SUDO is installed" + Test = { + $test = dnf list sudo | grep sudo.x86_64 + if ($test -match "sudo") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.3.2" + Task = "Ensure sudo commands use pty" + Test = { + $test = grep -rPi '^\h*Defaults\h+([^#\n\r]+,)?use_pty(,\h*\h+\h*)*\h*(#.*)?$' /etc/sudoers* + if ($test -match "/etc/sudoers:Defaults use_pty") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.3.3" + Task = "Ensure sudo log file exists" + Test = { + $test = grep -Ei '^\s*Defaults\s+logfile=\S+' /etc/sudoers /etc/sudoers.d/* + if ($test -match "/etc/sudoers:Defaults use_pty") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.3.4" + Task = "Ensure users must provide password for escalation" + Test = { + $test = grep -r "^[^#].*NOPASSWD" /etc/sudoers* + if ($test -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.3.5" + Task = "Ensure re-authentication for privilege escalation is not disabled globally" + Test = { + $test = grep -r "^[^#].*\!authenticate" /etc/sudoers* + if ($test -match "!authenticate") { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "5.3.6" + Task = "Ensure sudo authentication timeout is configured correctly" + Test = { + $test = grep -roP "timestamp_timeout=\K[0-9]*" /etc/sudoers* | cut -d ' ' -f 2 + if ($test -le 15) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.3.7" + Task = "Ensure access to the su command is restricted" + Test = { + $test1 = grep -Pi '^\h*auth\h+(?:required|requisite)\h+pam_wheel\.so\h+(?:[^#\n\r]+\h+)?((?!\2)(use_uid\b|group=\H+\b))\h+(?:[^#\n\r]+\h+)?((?!\1)(use_uid\b|group=\H+\b))(\h+.*)?$' /etc/pam.d/su + if ($test1 -match "auth required pam_wheel.so use_uid group=") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.1" + Task = "Ensure custom authselect profile is used" + Test = { + $test1 = authselect list | grep '^-\s*custom' + if ($test1 -eq $null) { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +# 5.4.2 ist leider schlecht beschrieben, die Pruefung ist mit ihren Parametern bestenfalls mangelhaft +[AuditTest] @{ + Id = "5.4.2" + Task = "Ensure authselect includes with-faillock" + Test = { + $test1 = grep pam_faillock.so /etc/pam.d/password-auth /etc/pam.d/system-auth + if ($test1 -match "/etc/authselect/password-auth:auth") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.5.1" + Task = "Ensure password creation requirements are configured" + Test = { + $test1 = grep ^minlen /etc/security/pwquality.conf | cut -d '=' -f 2 + if ($test1 -ge 14) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.5.2" + Task = "Ensure lockout for failed password attempts is configured" + Test = { + $test1 = grep -E '^\s*deny\s*=\s*[1-5]\b' /etc/security/faillock.conf | cut -d '=' -f 2 + $test2 = grep -E '^\s*unlock_time\s*=\s*(0|9[0-9][0-9]|[1-9][0-9][0-9][0-9]+)\b' /etc/security/faillock.conf | cut -d '=' -f 2 + if ($test1 -le 5 -and ($test2 -eq 0 -or $test2 -ge 900)) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.5.3" + Task = "Ensure password reuse is limited" + Test = { + $test1 = grep -P '^\h*password\h+(requisite|sufficient)\h+(pam_pwhistory\.so|pam_unix\.so)\h+([^#\n\r]+\h+)?remember=([5-9]|[1-9][0-9]+)\h*(\h+.*)?$' /etc/pam.d/system-auth + if ($test1 -match "remember=5") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.5.4" + Task = "Ensure password hashing algorithm is SHA-512 or yescrypt" + Test = { + $test1 = grep -Ei '^\s*crypt_style\s*=\s*(sha512|yescrypt)\b' /etc/libuser.conf + $test2 = grep -Ei '^\s*ENCRYPT_METHOD\s+(SHA512|yescrypt)\b' /etc/login.defs + if (($test2 -match "ENCRYPT_METHOD SHA512" -or $test2 -match "ENCRYPT_METHOD YESCRYPT") -and ($test1 -match "crypt_style = sha512" -or $test1 -match "crypt_style = yescrypt")) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.6.1.1" + Task = "Ensure password expiration is 365 days or less" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_5611_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_5611_2.sh" + $result2 = bash $resultScript2 + if ($result1 -le 365 -and $result2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.6.1.2" + Task = "Ensure minimum days between password changes is configured" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_5612_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_5612_2.sh" + $result2 = bash $resultScript2 + if ($result1 -ge 1 -and $result2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.6.1.3" + Task = "Ensure password expiration warning days is 7 or more" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_5613_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_5613_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "PASS_WARN_AGE\s*7" -and !($result2 -match "FAIL")) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.6.1.4" + Task = "Ensure inactive password lock is 30 days or less" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_5614_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_5614_2.sh" + $result2 = bash $resultScript2 + if ($result1 -ge 2 -and $result2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.6.1.5" + Task = "Ensure all users last password change date is in the past" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_5615.sh" + $result = bash $resultScript + if ($result -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.6.2" + Task = "Ensure system accounts are secured" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_562_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_562_2.sh" + $result2 = bash $resultScript2 + if ($result1 -eq $null -and $result2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.6.3" + Task = "Ensure default user shell timeout is 900 seconds or less" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + output1="" output2="" + [ -f /etc/bashrc ] && BRC="/etc/bashrc" + for f in "$BRC" /etc/profile /etc/profile.d/*.sh ; do + grep -Pq '^\s*([^#]+\s+)?TMOUT=(900|[1-8][0-9][0-9]|[1-9][0-9]|[1-9])\b' "$f" && grep -Pq '^\s*([^#]+;\s*)?readonly\s+TMOUT(\s+|\s*;|\s*$|=(900|[1-8][0-9][0-9]|[1-9][0-9]|[1-9]))\b' "$f" && grep -Pq '^\s*([^#]+;\s*)?export\s+TMOUT(\s+|\s*;|\s*$|=(900|[1-8][0-9][0-9]|[1-9][0-9]|[1-9]))\b' "$f" && output1="$f" + done + grep -Pq '^\s*([^#]+\s+)?TMOUT=(9[0-9][1-9]|9[1-9][0-9]|0+|[1-9]\d{3,})\b' /etc/profile /etc/profile.d/*.sh "$BRC" && output2=$(grep -Ps '^\s*([^#]+\s+)?TMOUT=(9[0-9][1-9]|9[1-9][0-9]|0+|[1-9]\d{3,})\b' /etc/profile /etc/profile.d/*.sh $BRC) + if [ -n "$output1" ] && [ -z "$output2" ]; then + echo -e "\nPASSED\n\nTMOUT is configured in: \"$output1\"\n" + else + [ -z "$output1" ] && echo -e "\nFAILED\n\nTMOUT is not configured\n" [ -n "$output2" ] && echo -e "\nFAILED\n\nTMOUT is incorrectly configured in: \"$output2\"\n" + fi +} +'@ + $script = bash -c $script_string + if ($script -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.6.4" + Task = "Ensure default group for the root account is GID 0" + Test = { + $test1 = grep "^root:" /etc/passwd | cut -f4 -d ':' + if ($test1 -eq 0) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.6.5" + Task = "Ensure default user shell timeout is 900 seconds or less" + Test = { + $resultScript1 = $scriptPath + "CIS100_RHEL9_565_1.sh" + $result1 = bash $resultScript1 + $resultScript2 = $scriptPath + "CIS100_RHEL9_565_2.sh" + $result2 = bash $resultScript2 + if ($result1 -match "umask is set" -and $result2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.6.6" + Task = "Ensure root password is set" + Test = { + $test1 = passwd -S root + if ($test1 -match "Password set") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + + +### Chapter 6 - System Maintenance + + +[AuditTest] @{ + Id = "6.1.1" + Task = "Ensure permissions on /etc/passwd are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/passwd + if ($test1 -match "644 0/root 0/root") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.2" + Task = "Ensure permissions on /etc/passwd are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/passwd- + if ($test1 -match "644 0/root 0/root") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.3" + Task = "Ensure permissions on /etc/group are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/group + if ($test1 -match "644 0/root 0/root") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.4" + Task = "Ensure permissions on /etc/group- are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/group- + if ($test1 -match "644 0/root 0/root") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.5" + Task = "Ensure permissions on /etc/shadow are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/shadow + if ($test1 -match "0 0/root 0/root") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.6" + Task = "Ensure permissions on /etc/shadow- are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/shadow- + if ($test1 -match "0 0/root 0/root") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.7" + Task = "Ensure permissions on /etc/gshadow are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/gshadow + if ($test1 -match "0 0/root 0/root") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.7" + Task = "Ensure permissions on /etc/gshadow are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/gshadow + if ($test1 -match "0 0/root 0/root") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.8" + Task = "Ensure permissions on /etc/gshadow- are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/gshadow- + if ($test1 -match "0 0/root 0/root") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.9" + Task = "Ensure no world writable files exist" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -0002 + if ($test1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.10" + Task = "Ensure no unowned files or directories exist" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nouser + if ($test1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.11" + Task = "Ensure no ungrouped files or directories exist" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nogroup + if ($test1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.12" + Task = "Ensure sticky bit is set on all world-writable directories" + Test = { + $test_string = "df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type d \( -perm -0002 -a ! -perm -1000 \) 2>/dev/null" + $test = bash -c $test_string + if ($test -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.13" + Task = "Audit SUID executables" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "6.1.14" + Task = "Audit SGID executables" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "6.1.15" + Task = "Audit system file permissions" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "6.2.1" + Task = "Ensure accounts in /etc/passwd use shadowed passwords" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_621.sh" + $result = bash $resultScript + if ($result -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.2" + Task = "Ensure /etc/shadow password fields are not empty" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_622.sh" + $result = bash $resultScript + if ($result -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.3" + Task = "Ensure all groups in /etc/passwd exist in /etc/group" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + for i in $(cut -s -d: -f4 /etc/passwd | sort -u ); do + grep -q -P "^.*?:[^:]*:$i:" /etc/group + if [ $? -ne 0 ]; then + echo "Group $i is referenced by /etc/passwd but does not exist in /etc/group" + fi + done +} +'@ + $script = bash -c $script_string + if ($script -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.4" + Task = "Ensure no duplicate UIDs exist" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + cut -f3 -d":" /etc/passwd | sort -n | uniq -c | while read x ; do + [ -z "$x" ] && break + set - $x + if [ $1 -gt 1 ]; then + users=$(awk -F: '($3 == n) { print $1 }' n=$2 /etc/passwd | xargs) + echo "Duplicate UID ($2): $users" + fi + done +} +'@ + $script = bash -c $script_string + if ($script -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.5" + Task = "Ensure no duplicate GIDs exist" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + cut -d: -f3 /etc/group | sort | uniq -d | while read x ; do + echo "Duplicate GID ($x) in /etc/group" + done +} +'@ + $script = bash -c $script_string + if ($script -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.6" + Task = "Ensure no duplicate user names exist" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + cut -d: -f1 /etc/passwd | sort | uniq -d | while read -r x; do + echo "Duplicate login name $x in /etc/passwd" + done +} +'@ + $script = bash -c $script_string + if ($script -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.7" + Task = "Ensure no duplicate group names exist" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + cut -d: -f1 /etc/group | sort | uniq -d | while read -r x; do + echo "Duplicate group name $x in /etc/group" + done +} +'@ + $script = bash -c $script_string + if ($script -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.8" + Task = "Ensure root PATH Integrity" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_628.sh" + $result = bash $resultScript + if ($result -match "is not a directory") { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.9" + Task = "Ensure root is the only UID 0 account" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_629.sh" + $result = bash $resultScript + if ($result -eq "root") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.10" + Task = "Ensure local interactive user home directories exist" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_6210.sh" + $result = bash $resultScript + if ($result -match "FAILED") { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.11" + Task = "Ensure local interactive users own their home directories" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_6210.sh" + $result = bash $resultScript + if ($result -match "FAILED") { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.12" + Task = "Ensure local interactive user home directories are mode 750 or more restrictive" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_6212.sh" + $result = bash $resultScript + if ($result -match "FAILED") { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.13" + Task = "Ensure no local interactive user has .netrc files" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_6213.sh" + $result = bash $resultScript + if ($result -match "FAILED") { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.14" + Task = "Ensure no local interactive user has .forward files" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_6214.sh" + $result = bash $resultScript + if ($result -match "FAILED") { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.15" + Task = "Ensure no local interactive user has .rhosts files" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_6215.sh" + $result = bash $resultScript + if ($result -match "FAILED") { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.16" + Task = "Ensure local interactive user dot files are not group or world writable" + Test = { + $resultScript = $scriptPath + "CIS100_RHEL9_6216.sh" + $result = bash $resultScript + if ($result -match "Failed") { + return $retNonCompliant + } else { + return $retCompliant + } + } +} diff --git a/ATAPAuditor/AuditGroups/Red Hat Enterprise Linux 9-CIS-2.0.0.ps1 b/ATAPAuditor/AuditGroups/Red Hat Enterprise Linux 9-CIS-2.0.0.ps1 new file mode 100644 index 0000000..5718492 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Red Hat Enterprise Linux 9-CIS-2.0.0.ps1 @@ -0,0 +1,4148 @@ +$rcTrue = "True" +$rcCompliant = "Compliant" +$rcFalse = "False" +$rcNone = "None" +$rcNonCompliant = "Non-Compliant" +$rcNonCompliantManualReviewRequired = "Manual review required" +$rcCompliantIPv6isDisabled = "IPv6 is disabled" + +$retCompliant = @{ + Message = $rcCompliant + Status = $rcTrue +} +$retNonCompliant = @{ + Message = $rcNonCompliant + Status = $rcFalse +} +$retCompliantIPv6Disabled = @{ + Message = $rcCompliantIPv6isDisabled + Status = $rcTrue +} +$retNonCompliantManualReviewRequired = @{ + Message = $rcNonCompliantManualReviewRequired + Status = $rcNone +} + +$IPv6Status_script = grep -Pqs '^\h*0\b' /sys/module/ipv6/parameters/disable && echo "IPv6 is enabled" || echo "IPv6 is not enabled" +$IPv6Status = bash -c $IPv6Status_script +if ($IPv6Status -match "is enabled") { + $IPv6Status = "enabled" +} +else { + $IPv6Status = "disabled" +} + +$parentPath = Split-Path -Parent -Path $PSScriptRoot +$scriptPath = $parentPath + "/Helpers/ShellScripts/RHEL9_CIS2.0.0/" +$commonPath = $parentPath + "/Helpers/ShellScripts/common/" + +[AuditTest] @{ + Id = "1.1.1.1" + Task = "Ensure cramfs kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.2" + Task = "Ensure freevxfs kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.3" + Task = "Ensure hfs kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.4" + Task = "Ensure hfsplus kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.5" + Task = "Ensure jffs2 kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.5.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.6" + Task = "Ensure squashfs kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.6.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.7" + Task = "Ensure udf kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.7.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.8" + Task = "Ensure usb-storage kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.8.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +# MISSING RULE: 1.1.1.9 - Ensure unused filesystems kernel modules are not available +[AuditTest] @{ + Id = "1.1.2.1.1" + Task = "Ensure /tmp is a separate partition" + Test = { + $result = findmnt --kernel /tmp | grep -E '\s/tmp\s' + if ($result -match "/tmp") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.1.2.1.2" + Task = "Ensure nodev option set on /tmp partition" + Test = { + $script = $commonPath + "1.1.2.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.1.3" + Task = "Ensure nosuid option set on /tmp partition" + Test = { + $script = $commonPath + "1.1.2.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.1.4" + Task = "Ensure noexec option set on /tmp partition" + Test = { + $result = findmnt --kernel /tmp | grep noexec + if ($result -match "/tmp") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.1.2.2.1" + Task = "Ensure /dev/shm is a separate partition" + Test = { + $result = findmnt --kernel /dev/shm + if ($result -match "/dev/shm") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.1.2.2.2" + Task = "Ensure nodev option set on /dev/shm partition" + Test = { + $script = $commonPath + "1.1.2.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.2.3" + Task = "Ensure nosuid option set on /dev/shm partition" + Test = { + $script = $commonPath + "1.1.2.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.2.4" + Task = "Ensure noexec option set on /dev/shm partition" + Test = { + $script = $commonPath + "1.1.2.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.3.1" + Task = "Ensure separate partition exists for /home" + Test = { + $result = findmnt --kernel /home + if ($result -match "/home") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.1.2.3.2" + Task = "Ensure nodev option set on /home partition" + Test = { + $script = $commonPath + "1.1.2.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.3.3" + Task = "Ensure nosuid option set on /home partition" + Test = { + $script = $commonPath + "1.1.2.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.4.1" + Task = "Ensure separate partition exists for /var" + Test = { + $result = findmnt --kernel /var + if ($result -match "/var") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + + +[AuditTest] @{ + Id = "1.1.2.4.2" + Task = "Ensure nodev option set on /var partition" + Test = { + $script = $commonPath + "1.1.2.4.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.4.3" + Task = "Ensure nosuid option set on /var partition" + Test = { + $script = $commonPath + "1.1.2.4.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.5.1" + Task = "Ensure separate partition exists for /var/tmp" + Test = { + $result = findmnt --kernel /var/tmp + if ($result -match "/var/tmp") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.1.2.5.2" + Task = "Ensure nodev option set on /var/tmp partition" + Test = { + $script = $commonPath + "1.1.2.5.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.5.3" + Task = "Ensure nosuid option set on /var/tmp partition" + Test = { + $script = $commonPath + "1.1.2.5.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.5.4" + Task = "Ensure noexec option set on /var/tmp partition" + Test = { + $script = $commonPath + "1.1.2.5.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.6.1" + Task = "Ensure separate partition exists for /var/log" + Test = { + $result = findmnt --kernel /var/log + if ($result -match "/var/log") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.1.2.6.2" + Task = "Ensure nodev option set on /var/log partition" + Test = { + $script = $commonPath + "1.1.2.6.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.6.3" + Task = "Ensure nosuid option set on /var/log partition" + Test = { + $script = $commonPath + "1.1.2.6.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.6.4" + Task = "Ensure noexec option set on /var/log partition" + Test = { + $script = $commonPath + "1.1.2.6.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.7.1" + Task = "Ensure separate partition exists for /var/log/audit" + Test = { + $result = findmnt --kernel /var/log/audit + if ($result -match "/var/log/audit") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.1.2.7.2" + Task = "Ensure nodev option set on /var/log/audit partition" + Test = { + $script = $commonPath + "1.1.2.7.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.7.3" + Task = "Ensure nosuid option set on /var/log/audit partition" + Test = { + $script = $commonPath + "1.1.2.7.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.7.4" + Task = "Ensure noexec option set on /var/log/audit partition" + Test = { + $script = $commonPath + "1.1.2.7.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.2.1.1" + Task = "Ensure GPG keys are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + + +[AuditTest] @{ + Id = "1.2.1.2" + Task = "Ensure gpgcheck is globally activated" + Test = { + $script = $scriptPath + "1.2.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.2.1.3" + Task = "Ensure repo_gpgcheck is globally activated" + Test = { + return $retNonCompliantManualReviewRequired + } +} + + +[AuditTest] @{ + Id = "1.2.1.4" + Task = "Ensure package manager repositories are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + + +[AuditTest] @{ + Id = "1.2.2.1" + Task = "Ensure updates, patches, and additional security software are installed" + Test = { + return $retNonCompliantManualReviewRequired + } +} + + +[AuditTest] @{ + Id = "1.3.1.1" + Task = "Ensure SELinux is installed" + Test = { + rpm -q libselinux 2>&1 >/dev/null + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.3.1.2" + Task = "Ensure SELinux is not disabled in bootloader configuration" + Test = { + $script = $scriptPath + "1.3.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.3.1.3" + Task = "Ensure SELinux policy is configured" + Test = { + $script = $scriptPath + "1.3.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.3.1.4" + Task = "Ensure the SELinux mode is not disabled" + Test = { + $result1 = getenforce + $result2 = grep -Ei '^\s*SELINUX=(enforcing|permissive)' /etc/selinux/config + if (($result1 -match "Enforcing" -or $result1 -match "Permissive") -and ($result2 -match "SELINUX=enforcing" -or $result2 -match "SELINUX=permissive")) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.3.1.5" + Task = "Ensure the SELinux mode is enforcing" + Test = { + $script = $scriptPath + "1.3.1.5.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +# MISSING RULE: 1.3.1.6 - Ensure no unconfined services exist +[AuditTest] @{ + Id = "1.3.1.7" + Task = "Ensure the MCS Translation Service (mcstrans) is not installed" + Test = { + $result = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/motd + if ($result -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.3.1.8" + Task = "Ensure SETroubleshoot is not installed" + Test = { + rpm -q setroubleshoot 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.4.1" + Task = "Ensure bootloader password is set" + Test = { + $result = awk -F. '/^\s*GRUB2_PASSWORD/ {print $1"."$2"."$3}' /boot/grub2/user.cfg + if ($result -match "GRUB2_PASSWORD=grub.pbkdf2.sha512") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.4.2" + Task = "Ensure access to bootloader config is configured" + Test = { + $script = $commonPath + "1.4.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.5.1" + Task = "Ensure address space layout randomization is enabled" + Test = { + $script = $commonPath + "1.5.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.5.2" + Task = "Ensure ptrace_scope is restricted" + Test = { + $script = $commonPath + "1.5.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.5.3" + Task = "Ensure core dump backtraces are disabled" + Test = { + $script = $scriptPath + "1.5.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.5.4" + Task = "Ensure core dump storage is disabled" + Test = { + $script = $scriptPath + "1.5.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.6.1" + Task = "Ensure system wide crypto policy is not set to legacy" + Test = { + $script = $scriptPath + "1.6.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.6.2" + Task = "Ensure system wide crypto policy is not set in sshd configuration" + Test = { + $script = $scriptPath + "1.6.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +# MISSING RULE: 1.6.3 - Ensure system wide crypto policy disables sha1 hash and signature support +# MISSING RULE: 1.6.4 - Ensure system wide crypto policy disables macs less than 128 bits +# MISSING RULE: 1.6.5 - Ensure system wide crypto policy disables cbc for ssh +# MISSING RULE: 1.6.6 - Ensure system wide crypto policy disables chacha20-poly1305 for ssh +# MISSING RULE: 1.6.7 - Ensure system wide crypto policy disables EtM for ssh +[AuditTest] @{ + Id = "1.7.1" + Task = "Ensure message of the day is configured properly" + Test = { + $script = $scriptPath + "1.7.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.7.2" + Task = "Ensure local login warning banner is configured properly" + Test = { + $result = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue + if ($result -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.7.3" + Task = "Ensure remote login warning banner is configured properly" + Test = { + $result = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue.net + if ($result -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.7.4" + Task = "Ensure access to /etc/motd is configured" + Test = { + $script = $scriptPath + "1.7.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.7.5" + Task = "Ensure permissions on /etc/issue are configured" + Test = { + $result = stat -c "%a" /etc/issue + if ($result -eq 644) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.7.6" + Task = "Ensure permissions on /etc/issue.net are configured" + Test = { + $result = stat -c "%a" /etc/issue.net + if ($result -eq 644) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.8.1" + Task = "Ensure GNOME Display Manager is removed" + Test = { + rpm -q gdm 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.8.2" + Task = "Ensure GDM login banner is configured" + Test = { + $resultScript = $scriptPath + "1.8.2.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.8.3" + Task = "Ensure GDM disable-user-list option is enabled" + Test = { + $resultScript = $scriptPath + "1.8.3.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.8.4" + Task = "Ensure GDM screen locks when the user is idle" + Test = { + $resultScript = $scriptPath + "1.8.4.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.8.5" + Task = "Ensure GDM screen locks cannot be overridden" + Test = { + $resultScript = $scriptPath + "1.8.5.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.8.6" + Task = "Ensure GDM automatic mounting of removable media is disabled" + Test = { + $resultScript = $scriptPath + "1.8.6.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.8.7" + Task = "Ensure GDM disabling automatic mounting of removable media is not overridden" + Test = { + $resultScript = $scriptPath + "1.8.7.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.8.8" + Task = "Ensure GDM autorun-never is enabled" + Test = { + $resultScript = $scriptPath + "1.8.8.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.8.9" + Task = "Ensure GDM autorun-never is not overridden" + Test = { + $resultScript = $scriptPath + "1.8.9.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.8.10" + Task = "Ensure XDMCP is not enabled" + Test = { + $script = $scriptPath + "1.8.10.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "2.1.1" + Task = "Ensure time synchronization is in use" + Test = { + rpm -q chrony 2>&1 >/dev/null + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.1.2" + Task = "Ensure chrony is configured" + Test = { + $test = grep -E "^(server|pool)" /etc/chrony.conf | grep OPTIONS\s*-u\s*chrony + if ($test -match "OPTIONS") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.1.3" + Task = "Ensure dhcp server services are not in use" + Test = { + rpm -q isc-dhcp-server 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + $test2 = systemctl is-enabled 2>/dev/null isc-dhcp-server.service + if (! $?) { + $test2 = systemctl is-enabled 2>/dev/null isc-dhcp-server6.service + if (! $?) { + return $retCompliant + } + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.4" + Task = "Ensure dns server services are not in use" + Test = { + rpm -q bind9 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + $test2 = systemctl is-enabled 2>/dev/null bind9.service + if (! $?) { + return $retCompliant + } + } + return $retNonCompliant + } +} + +# MISSING RULE: 2.1.5 - Ensure dnsmasq services are not in use +[AuditTest] @{ + Id = "2.1.6" + Task = "Ensure samba file server services are not in use" + Test = { + rpm -q samba 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + $test2 = systemctl is-enabled 2>/dev/null samba.service + if (! $?) { + return $retCompliant + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.7" + Task = "Ensure ftp server services are not in use" + Test = { + rpm -q vsftpd 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + $test2 = systemctl is-enabled 2>/dev/null vsftpd.service + if (! $?) { + return $retCompliant + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.8" + Task = "Ensure message access server services are not in use" + Test = { + rpm -q dovecot-imapd 2>&1 >/dev/null + if ($?) { + return $retNonCompliant + } + rpm -q dovecot-pop3d 2>&1 >/dev/null + if ($?) { + return $retNonCompliant + } + $test3 = systemctl is-enabled 2>/dev/null dovecot.socket + if (! $?) { + $test4 = systemctl is-enabled 2>/dev/null dovecot.service + if (! $?) { + return $retCompliant + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.9" + Task = "Ensure network file system services are not in use" + Test = { + rpm -q nfs-kernel-server 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + $test2 = systemctl is-enabled 2>/dev/null nfs-kernel.service + if (! $?) { + return $retCompliant + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.10" + Task = "Ensure nis server services are not in use" + Test = { + rpm -q ypserv 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + $test2 = systemctl is-enabled 2>/dev/null ypserv.service + if (! $?) { + return $retCompliant + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.11" + Task = "Ensure print server services are not in use" + Test = { + rpm -q cups 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + $test2 = systemctl is-enabled 2>/dev/null cups.service + if (! $?) { + $test3 = systemctl is-enabled 2>/dev/null cups.socket + if (! $?) { + return $retCompliant + } + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.12" + Task = "Ensure rpcbind services are not in use" + Test = { + rpm -q rpcbind 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + $test2 = systemctl is-enabled 2>/dev/null rpcbind.service + if (! $?) { + $test3 = systemctl is-enabled 2>/dev/null rpcbind.socket + if (! $?) { + return $retCompliant + } + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.13" + Task = "Ensure rsync services are not in use" + Test = { + $script = $commonPath + "2.1.13.sh" + bash $script + if ($?) { + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.15" + Task = "Ensure snmp services are not in use" + Test = { + rpm -q snmpd 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + $test2 = systemctl is-enabled 2>/dev/null snmpd.service + if (! $?) { + return $retCompliant + } + } + return $retNonCompliant + } +} + +# MISSING RULE: 2.1.15 - Ensure telnet server services are not in use +[AuditTest] @{ + Id = "2.1.16" + Task = "Ensure tftp server services are not in use" + Test = { + rpm -q tftpd-hpa 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + $test2 = systemctl is-enabled 2>/dev/null tftpd-hpa.service + if (! $?) { + return $retCompliant + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.17" + Task = "Ensure web proxy server services are not in use" + Test = { + rpm -q squid 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + $test2 = systemctl is-enabled 2>/dev/null squid.service + if (! $?) { + return $retCompliant + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.18" + Task = "Ensure web server services are not in use" + Test = { + rpm -q apache2 2>&1 >/dev/null + if ($?) { + return $retNonCompliant + } + rpm -q ginx 2>&1 >/dev/null + if ($?) { + return $retNonCompliant + } + else { + $services = 'apache2.service', 'apache2.socket', 'nginx.service', 'nginx.socket' + $test3 = "disabled" + foreach ($service in $services) { + $test4 = systemctl is-enabled $service 2>/dev/null + if ($?) { + $test3 = "enabled" + } + } + if ($test3 -match "disabled") { + return $retCompliant + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.19" + Task = "Ensure xinetd services are not in use" + Test = { + rpm -q xinetd 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + $test2 = systemctl is-enabled 2>/dev/null xinetd.service + if (! $?) { + return $retCompliant + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.1.20" + Task = "Ensure X window server services are not in use" + Test = { + rpm -q xserver-commen 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + return $retNonCompliant + } +} + +# MISSING RULE: 2.1.21 - Ensure mail transfer agents are configured for local-only mode +[AuditTest] @{ + Id = "2.1.22" + Task = "Ensure only approved services are listening on a network interface" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "2.2.1" + Task = "Ensure xorg-x11-server-common is not installed" + Test = { + rpm -q xorg-x11-server-common 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.2.2" + Task = "Ensure Avahi Server is not installed" + Test = { + rpm -q avahi 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.2.3" + Task = "Ensure CUPS is not installed" + Test = { + rpm -q cups 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.2.4" + Task = "Ensure DHCP Server is not installed" + Test = { + rpm -q dhcp-server 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.2.5" + Task = "Ensure DNS Server is not installed" + Test = { + rpm -q bind 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.3.2" + Task = "Ensure LDAP client is not installed" + Test = { + rpm -q openldap-clients 2>&1 >/dev/null + if (! $?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.3.3" + Task = "Ensure chrony is not run as the root user" + Test = { + $script = $scriptPath + "2.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "2.4.1.1" + Task = "Ensure cron daemon is enabled and active" + Test = { + $test1 = systemctl is-enabled cron + $test2 = systemctl status cron | grep 'Active: active (running) ' + if ($test1 -eq "enabled" -and $test2 -match "running") { + return $retCompliant + } + return $retCompliant + } +} + +[AuditTest] @{ + Id = "2.4.1.2" + Task = "Ensure permissions on /etc/crontab are configured" + Test = { + $result1 = stat -c "%a" /etc/crontab + if ($result1 -eq 600 ) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.4.1.3" + Task = "Ensure permissions on /etc/cron.hourly are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.hourly + if ($result1 -eq 700 ) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.4.1.4" + Task = "Ensure permissions on /etc/cron.daily are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.daily + if ($result1 -eq 700 ) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.4.1.5" + Task = "Ensure permissions on /etc/cron.weekly are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.weekly + if ($result1 -eq 700 ) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.4.1.6" + Task = "Ensure permissions on /etc/cron.monthly are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.monthly + if ($result1 -eq 700 ) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.4.1.7" + Task = "Ensure permissions on /etc/cron.d are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.d + if ($result1 -eq 700 ) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "2.4.1.8" + Task = "Ensure crontab is restricted to authorized users" + Test = { + $script = $commonPath + "2.4.1.8.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.4.2.1" + Task = "Ensure at is restricted to authorized users" + Test = { + $script = $commonPath + "2.4.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.1.1" + Task = "Ensure IPv6 status is identified" + Test = { + return $retNonCompliantManualReviewRequired + } +} + + +[AuditTest] @{ + Id = "3.1.2" + Task = "Ensure wireless interfaces are disabled" + Test = { + $script = $commonPath + "3.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.1.3" + Task = "Ensure TIPC is disabled" + Test = { + $resultScript = $scriptPath + "3.1.3.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "3.2.1" + Task = "Ensure dccp kernel module is not available" + Test = { + $script = $commonPath + "3.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.2.2" + Task = "Ensure tipc kernel module is not available" + Test = { + $script = $commonPath + "3.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.2.3" + Task = "Ensure rds kernel module is not available" + Test = { + $script = $commonPath + "3.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.2.4" + Task = "Ensure sctp kernel module is not available" + Test = { + $script = $commonPath + "3.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.1" + Task = "Ensure ip forwarding is disabled" + Test = { + $script = $commonPath + "3.3.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.2" + Task = "Ensure packet redirect sending is disabled" + Test = { + $script = $commonPath + "3.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.3" + Task = "Ensure bogus icmp responses are ignored" + Test = { + $script = $commonPath + "3.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.4" + Task = "Ensure broadcast icmp requests are ignored" + Test = { + $script = $commonPath + "3.3.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.5" + Task = "Ensure icmp redirects are not accepted" + Test = { + $script = $commonPath + "3.3.5.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.6" + Task = "Ensure secure icmp redirects are not accepted" + Test = { + $script = $commonPath + "3.3.6.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.7" + Task = "Ensure reverse path filtering is enabled" + Test = { + $script = $commonPath + "3.3.7.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.8" + Task = "Ensure source routed packets are not accepted" + Test = { + $script = $commonPath + "3.3.8.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.9" + Task = "Ensure suspicious packets are logged" + Test = { + $script = $commonPath + "3.3.9.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.10" + Task = "Ensure tcp syn cookies is enabled" + Test = { + $script = $commonPath + "3.3.10.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.11" + Task = "Ensure ipv6 router advertisements are not accepted" + Test = { + $script = $commonPath + "3.3.11.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "4.1.1" + Task = "Ensure nftables is installed" + Test = { + rpm -q nftables 2>&1 >/dev/null + if ($result -match "nftables-") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "4.1.2" + Task = "Ensure a single firewall configuration utility is in use" + Test = { + $resultScript = $scriptPath + "4.1.2.sh" + $result = bash $resultScript + if ($result -match "PASS") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "4.2.1" + Task = "Ensure firewalld drops unnecessary services and ports" + Test = { + return $retNonCompliantManualReviewRequired + } +} + + +# MISSING RULE: 4.2.2 - Ensure firewalld loopback traffic is configured +[AuditTest] @{ + Id = "4.3.1" + Task = "Ensure nftables base chains exist" + Test = { + try { + $test1 = nft list ruleset | grep 'hook input' + $test2 = nft list ruleset | grep 'hook forward' + $test3 = nft list ruleset | grep 'hook output' + if ($test1 -match "type filter hook input" -and $test2 -match "type filter hook forward" -and $test3 -match "type filter hook output") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch { + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} + + +[AuditTest] @{ + Id = "4.3.2" + Task = "Ensure nftables established connections are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + + +[AuditTest] @{ + Id = "4.3.3" + Task = "Ensure nftables default deny firewall policy" + Test = { + $result1 = systemctl --quiet is-enabled nftables.service && nft list ruleset | grep 'hook input' | grep -v 'policy drop' + $result2 = systemctl --quiet is-enabled nftables.service && nft list ruleset | grep 'hook forward' | grep -v 'policy drop' + if ($result1 -eq $null -and $result2 -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +### Chapter 4 - Logging and Auditing + +[AuditTest] @{ + Id = "4.3.4" + Task = "Ensure nftables loopback traffic is configured" + Test = { + try { + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + if ($isIPv6Disabled -ne $true) { + $test1 = nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept' + $test2 = nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr' + if ($test1 -match 'iif "lo" accept' -and $test2 -match "ip saddr 127.0.0.0/8 counter packets 0 bytes 0 drop") { + return $retCompliant + } + } + else { + $test = nft list ruleset | awk '/hook input/,/}/' | grep 'ip6 saddr' + if ($test -match 'ip6 saddr ::1 counter packets 0 bytes 0 drop') { + return $retCompliant + } + } + return $retNonCompliant + } + catch { + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} + +[AuditTest] @{ + Id = "5.1.1" + Task = "Ensure cron daemon is enabled" + Test = { + $result1 = systemctl is-enabled crond + if ($result1 -match "enabled") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.1.2" + Task = "Ensure permissions on /etc/crontab are configured" + Test = { + $result1 = stat -c "%a" /etc/crontab + if ($result1 -eq 600 ) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.1.3" + Task = "Ensure permissions on SSH public host key files are configured" + Test = { + $script = $commonPath + "5.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.4" + Task = "Ensure permissions on /etc/cron.daily are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.daily + if ($result1 -eq 700 ) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.1.5" + Task = "Ensure permissions on /etc/cron.weekly are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.weekly + if ($result1 -eq 700 ) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.1.6" + Task = "Ensure permissions on /etc/cron.monthly are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.monthly + if ($result1 -eq 700 ) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.1.7" + Task = "Ensure permissions on /etc/cron.d are configured" + Test = { + $result1 = stat -c "%a" /etc/cron.d + if ($result1 -eq 700 ) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.1.8" + Task = "Ensure cron is restricted to authorized users" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + if rpm -q cronie 2>&1 >/dev/null >/dev/null; then + [ -e /etc/cron.deny ] && echo "Fail: cron.deny exists" + if [ ! -e /etc/cron.allow ]; then + echo "Fail: cron.allow doesn't exist" + else + ! stat -Lc "%a" /etc/cron.allow | grep -Eq "[0,2,4,6]00" && echo "Fail: cron.allow mode too permissive" + ! stat -Lc "%u:%g" /etc/cron.allow | grep -Eq "^0:0$" && echo "Fail: cron.allow owner and/or group not root" + fi + if [ ! -e /etc/cron.deny ] && [ -e /etc/cron.allow ] && stat -Lc "%a" /etc/cron.allow | grep -Eq "[0,2,4,6]00" \ && stat -Lc "%u:%g" /etc/cron.allow | grep -Eq "^0:0$"; then + echo "Pass" + fi + else + echo "PASS: cron is not installed on the system" + fi +} +'@ + $script = bash -c $script_string + if ($script -match "PASS") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.1.9" + Task = "Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured" + Test = { + $script = $scriptPath + "5.1.9.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.10" + Task = "Ensure sshd DisableForwarding is enabled" + Test = { + $script = $scriptPath + "5.1.10.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.11" + Task = "Ensure sshd GSSAPIAuthentication is disabled" + Test = { + $script = $scriptPath + "5.1.11.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.12" + Task = "Ensure sshd HostbasedAuthentication is disabled" + Test = { + $script = $scriptPath + "5.1.12.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.13" + Task = "Ensure sshd IgnoreRhosts is enabled" + Test = { + $script = $scriptPath + "5.1.13.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.14" + Task = "Ensure sshd LoginGraceTime is configured" + Test = { + $script = $scriptPath + "5.1.14.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.15" + Task = "Ensure sshd LogLevel is configured" + Test = { + $script = $scriptPath + "5.1.15.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.16" + Task = "Ensure sshd MaxAuthTries is configured" + Test = { + $script = $commonPath + "5.1.16.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.17" + Task = "Ensure sshd MaxStartups is configured" + Test = { + $script = $scriptPath + "5.1.17.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.18" + Task = "Ensure sshd MaxSessions is configured" + Test = { + $script = $scriptPath + "5.1.18.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.19" + Task = "Ensure sshd PermitEmptyPasswords is disabled" + Test = { + $script = $commonPath + "5.1.19.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.20" + Task = "Ensure sshd PermitRootLogin is disabled" + Test = { + $script = $commonPath + "5.1.20.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.21" + Task = "Ensure sshd PermitUserEnvironment is disabled" + Test = { + $script = $commonPath + "5.1.21.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.22" + Task = "Ensure sshd UsePAM is enabled" + Test = { + $script = $commonPath + "5.1.22.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.1" + Task = "Ensure permissions on /etc/ssh/sshd_config are configured" + Test = { + $result1 = stat -Lc "%n %a %u/%U %g/%G" /etc/ssh/sshd_config + if ($result1 -match "/etc/ssh/sshd_config 600 0/root 0/root") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.2.2" + Task = "Ensure sudo commands use pty" + Test = { + $script = $commonPath + "5.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.3" + Task = "Ensure sudo log file exists" + Test = { + $script = $commonPath + "5.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.4" + Task = "Ensure SSH access is limited" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$' + $test2 = grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$' /etc/ssh/sshd_config + if ($test1 -match "allowusers " -or $test1 -match "allowgroups " -or $test1 -match "denyusers " -or $test1 -match "denygroups " -or + $test2 -match "allowusers " -or $test2 -match "allowgroups " -or $test2 -match "denyusers " -or $test2 -match "denygroups ") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.2.5" + Task = "Ensure SSH LogLevel is appropriate" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$' + $test2 = grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$' /etc/ssh/sshd_config + if (($test1 -match "allowusers " -or $test1 -match "allowgroups " -or $test1 -match "denyusers " -or $test1 -match "denygroups ") -and + ($test2 -match "allowusers " -or $test2 -match "allowgroups " -or $test2 -match "denyusers " -or $test2 -match "denygroups ")) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.2.6" + Task = "Ensure sudo authentication timeout is configured correctly" + Test = { + $script = $commonPath + "5.2.6.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.7" + Task = "Ensure SSH root login is disabled" + Test = { + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permitrootlogin + $test2 = grep -Ei '^\s*PermitRootLogin\s+yes' /etc/ssh/sshd_config + if ($test1 -match "permitrootlogin no" -and $test2 -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.3.1.1" + Task = "Ensure latest version of pam is installed" + Test = { + rpm -q libpam-runtime 2>&1 >/dev/null + if ($?) { + return $retNonCompliant + } + return $retCompliant + } +} + +# MISSING RULE: 5.3.1.2 - Ensure latest version of authselect is installed +# MISSING RULE: 5.3.1.3 - Ensure latest version of libpwquality is installed +# MISSING RULE: 5.3.2.1 - Ensure active authselect profile includes pam modules +[AuditTest] @{ + Id = "5.3.2.2" + Task = "Ensure pam_faillock module is enabled" + Test = { + $script = $scriptPath + "5.3.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.2.3" + Task = "Ensure pam_pwquality module is enabled" + Test = { + $script = $scriptPath + "5.3.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.2.4" + Task = "Ensure pam_pwhistory module is enabled" + Test = { + $script = $scriptPath + "5.3.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.2.5" + Task = "Ensure pam_unix module is enabled" + Test = { + $script = $scriptPath + "5.3.2.5.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.1.1" + Task = "Ensure password failed attempts lockout is configured" + Test = { + $script = $commonPath + "5.3.3.1.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.1.2" + Task = "Ensure password unlock time is configured" + Test = { + $script = $commonPath + "5.3.3.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.1.3" + Task = "Ensure password failed attempts lockout includes root account" + Test = { + $script = $commonPath + "5.3.3.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.1" + Task = "Ensure password number of changed characters is configured" + Test = { + $script = $commonPath + "5.3.3.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.2" + Task = "Ensure password length is configured" + Test = { + $script = $commonPath + "5.3.3.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.3" + Task = "Ensure password complexity is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "5.3.3.2.4" + Task = "Ensure password same consecutive characters is configured" + Test = { + $script = $commonPath + "5.3.3.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.5" + Task = "Ensure password maximum sequential characters is configured" + Test = { + $script = $commonPath + "5.3.3.2.5.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.6" + Task = "Ensure password dictionary check is enabled" + Test = { + $script = $commonPath + "5.3.3.2.6.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.7" + Task = "Ensure password quality is enforced for the root user" + Test = { + $script = $scriptPath + "5.3.3.2.7.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.3.1" + Task = "Ensure password history remember is configured" + Test = { + $script = $scriptPath + "5.3.3.3.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.3.2" + Task = "Ensure password history is enforced for the root user" + Test = { + $script = $scriptPath + "5.3.3.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.3.3" + Task = "Ensure pam_pwhistory includes use_authtok" + Test = { + $script = $commonPath + "5.3.3.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.3.3.4.1" + Task = "Ensure pam_unix does not include nullok" + Test = { + $script = $commonPath + "5.3.3.4.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.3.3.4.2" + Task = "Ensure pam_unix does not include remember" + Test = { + $script = $scriptPath + "5.3.3.4.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.4.3" + Task = "Ensure pam_unix includes a strong password hashing algorithm" + Test = { + $script = $scriptPath + "5.3.3.4.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.4.4" + Task = "Ensure pam_unix includes use_authtok" + Test = { + $script = $commonPath + "5.3.3.4.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.1.1" + Task = "Ensure password expiration is configured" + Test = { + $script = $commonPath + "5.4.1.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.2" + Task = "Ensure minimum password days is configured" + Test = { + $script = $commonPath + "5.4.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.3" + Task = "Ensure password expiration warning days is configured" + Test = { + $script = $commonPath + "5.4.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.4" + Task = "Ensure strong password hashing algorithm is configured" + Test = { + $script = $commonPath + "5.4.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.5" + Task = "Ensure inactive password lock is configured" + Test = { + $script = $commonPath + "5.4.1.5.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.6" + Task = "Ensure all users last password change date is in the past" + Test = { + $resultScript = $scriptPath + "5.4.1.6.sh" + $result = bash $resultScript + if ($result -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.4.2.1" + Task = "Ensure root is the only UID 0 account" + Test = { + $resultScript = $scriptPath + "5.4.2.1.sh" + $result = bash $resultScript + if ($result -eq "root") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.2.2" + Task = "Ensure root is the only GID 0 account" + Test = { + $test1 = grep "^root:" /etc/passwd | cut -f4 -d ':' + if ($test1 -eq 0) { + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.4.2.3" + Task = "Ensure group root is the only GID 0 group" + Test = { + $script = $commonPath + "5.4.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + +# MISSING RULE: 5.4.2.4 - Ensure root account access is controlled +[AuditTest] @{ + Id = "5.4.2.5" + Task = "Ensure root PATH Integrity" + Test = { + $resultScript = $scriptPath + "5.4.2.5.sh" + $result = bash $resultScript + if ($result -match "is not a directory") { + return $retNonCompliant + } + else { + return $retCompliant + } + } +} + + +[AuditTest] @{ + Id = "5.4.2.6" + Task = "Ensure root user umask is configured" + Test = { + $script = $commonPath + "5.4.2.6.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.2.7" + Task = "Ensure system accounts do not have a valid login shell" + Test = { + $script = $commonPath + "5.4.2.7.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.2.8" + Task = "Ensure accounts without a valid login shell are locked" + Test = { + $script = $commonPath + "5.4.2.8.sh" + bash $script + if ($?) { + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "5.4.3.1" + Task = "Ensure nologin is not listed in /etc/shells" + Test = { + $script = $commonPath + "5.4.3.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.3.2" + Task = "Ensure default user shell timeout is configured" + Test = { + $script = $commonPath + "5.4.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.3.3" + Task = "Ensure default user umask is configured" + Test = { + $script = $commonPath + "5.4.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.1.1" + Task = "Ensure permissions on /etc/passwd are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/passwd + if ($test1 -match "644 0/root 0/root") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "6.1.2" + Task = "Ensure permissions on /etc/passwd are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/passwd- + if ($test1 -match "644 0/root 0/root") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "6.1.3" + Task = "Ensure cryptographic mechanisms are used to protect the integrity of audit tools" + Test = { + $script = $commonPath + "6.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.1.1" + Task = "Ensure journald service is enabled and active" + Test = { + $test1 = systemctl is-enabled rsyslog + if ($test1 -match "enabled") { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} + +[AuditTest] @{ + Id = "6.2.1.2" + Task = "Ensure journald log file access is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "6.2.1.3" + Task = "Ensure journald log file rotation is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +# MISSING RULE: 6.2.1.4 - Ensure only one logging system is in use + +[AuditTest] @{ + Id = "6.2.2.1.1" + Task = "Ensure systemd-journal-remote is installed" + Test = { + rpm -q systemd-journal-remote 2>&1 >/dev/null + if ($?) { + return $retCompliant + } + return $retNonCompliant + } +} + + +# MISSING RULE: 6.2.2.1.2 - Ensure systemd-journal-upload authentication is configured + +[AuditTest] @{ + Id = "6.2.2.1.3" + Task = "Ensure systemd-journal-upload is enabled and active" + Test = { + $test1 = systemctl is-enabled systemd-journal-upload.service + $test2 = systemctl is-active systemd-journal-upload.service + if ($test1 -eq "enabled" -and $test2 -match "active") { + return $retCompliant + } + return $retCompliant + } +} + +[AuditTest] @{ + Id = "6.2.2.1.4" + Task = "Ensure systemd-journal-remote service is not in use" + Test = { + $script = $scriptPath + "6.2.2.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.2.2" + Task = "Ensure journald ForwardToSyslog is disabled" + Test = { + $script = $scriptPath + "6.2.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.2.3" + Task = "Ensure journald Compress is configured" + Test = { + $script = $scriptPath + "6.2.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.2.4" + Task = "Ensure journald Storage is configured" + Test = { + $script = $scriptPath + "6.2.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.3.1" + Task = "Ensure rsyslog is installed" + Test = { + rpm -q rsyslog 2>&1 >/dev/null + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +# MISSING RULE: 6.2.3.2 - Ensure rsyslog service is enabled and active +[AuditTest] @{ + Id = "6.2.3.3" + Task = "Ensure journald is configured to send logs to rsyslog" + Test = { + rpm -q systemd-journal-remote 2>&1 >/dev/null + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "6.2.3.4" + Task = "Ensure rsyslog log file creation mode is configured" + Test = { + $script = $scriptPath + "6.2.3.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +# MISSING RULE: 6.2.3.5 - Ensure rsyslog logging is configured +[AuditTest] @{ + Id = "6.2.3.6" + Task = "Ensure rsyslog is configured to send logs to a remote log host" + Test = { + return $retNonCompliantManualReviewRequired + } +} + + +[AuditTest] @{ + Id = "6.2.3.7" + Task = "Ensure rsyslog is not configured to receive logs from a remote client" + Test = { + $script = $scriptPath + "6.2.3.7.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +# MISSING RULE: 6.2.3.8 - Ensure rsyslog logrotate is configured + +[AuditTest] @{ + Id = "6.2.4.1" + Task = "Ensure access to all logfiles has been configured" + Test = { + $fileListAll = find /var/log -type f -ls + $fileListFiltered = find /var/log -type f -ls | grep "\-....\-\-\-\-\-" + if ($fileListAll.Count -eq $fileListFiltered.Count) { + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "6.3.1.1" + Task = "Ensure auditd packages are installed" + Test = { + rpm -q auditd 2>&1 >/dev/null + if (! $?) { + return $retNonCompliant + } + rpm -q audispd-plugins 2>&1 >/dev/null + if (! $?) { + return $retNonCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "6.3.1.2" + Task = "Ensure auditing for processes that start prior to auditd is enabled" + Test = { + $script = $scriptPath + "6.3.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.1.3" + Task = "Ensure audit_backlog_limit is sufficient" + Test = { + $script = $scriptPath + "6.3.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.3.1.4" + Task = "Ensure auditd service is enabled and active" + Test = { + $test1 = systemctl is-enabled auditd + if ($test1 -match "enabled") { + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "6.3.2.1" + Task = "Ensure audit log storage size is configured" + Test = { + $script = $commonPath + "6.3.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.2.2" + Task = "Ensure audit logs are not automatically deleted" + Test = { + $script = $commonPath + "6.3.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.2.3" + Task = "Ensure system is disabled when audit logs are full" + Test = { + $result1 = grep space_left_action /etc/audit/auditd.conf + $result2 = grep action_mail_acct /etc/audit/auditd.conf + $result3 = grep -E 'admin_space_left_action\s*=\s*(halt|single)' /etc/audit/auditd.conf + if ($result1 -match "space_left_action = email" -and $result2 -match "action_mail_acct = root" -and ($result3 -match "admin_space_left_action = halt" -or $result3 -match "admin_space_left_action = single")) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "6.3.2.4" + Task = "Ensure system warns when audit logs are low on space" + Test = { + $test1 = grep -Pi -- '^\h*space_left_action\h*=\h*\w+\b' /etc/audit/auditd.conf | awk '{print $3}' + if ($test1 -match "^(email|exec|single|halt)$") { + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "6.3.3.1" + Task = "Ensure changes to system administration scope (sudoers) is collected" + Test = { + $script = $commonPath + "6.3.3.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.2" + Task = "Ensure actions as another user are always logged" + Test = { + $script = $commonPath + "6.3.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.3" + Task = "Ensure events that modify the sudo log file are collected" + Test = { + $script = $commonPath + "6.3.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.4" + Task = "Ensure events that modify date and time information are collected" + Test = { + $script = $commonPath + "6.3.3.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.5" + Task = "Ensure events that modify the system's network environment are collected" + Test = { + $script = $commonPath + "6.3.3.5.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.6" + Task = "Ensure use of privileged commands are collected" + Test = { + $script = $commonPath + "6.3.3.6.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.7" + Task = "Ensure unsuccessful file access attempts are collected" + Test = { + $script = $commonPath + "6.3.3.7.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.8" + Task = "Ensure events that modify user/group information are collected" + Test = { + $script = $commonPath + "6.3.3.8.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.9" + Task = "Ensure discretionary access control permission modification events are collected" + Test = { + $script = $commonPath + "6.3.3.9.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.10" + Task = "Ensure successful file system mounts are collected" + Test = { + $script = $commonPath + "6.3.3.10.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.11" + Task = "Ensure session initiation information is collected" + Test = { + $script_string1 = @' +#!/usr/bin/env bash +{ + awk '/^ *-w/ &&(/\/var\/run\/utmp/ ||/\/var\/log\/wtmp/ ||/\/var\/log\/btmp/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules +} +'@ + $script_string2 = @' +#!/usr/bin/env bash +{ + auditctl -l | awk '/^ *-w/ &&(/\/var\/run\/utmp/ ||/\/var\/log\/wtmp/ ||/\/var\/log\/btmp/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' +} +'@ + $result1 = bash -c $script_string1 + $result2 = bash -c $script_string2 + if ($result1 -match "-w /var/run/utmp -p wa -k session" -and $result1 -match "-w /var/log/wtmp -p wa -k session" -and $result1 -match "-w /var/log/btmp -p wa -k session" -and + $result2 -match "-w /var/run/utmp -p wa -k session" -and $result2 -match "-w /var/log/wtmp -p wa -k session" -and $result2 -match "-w /var/log/btmp -p wa -k session") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + + +[AuditTest] @{ + Id = "6.3.3.12" + Task = "Ensure login and logout events are collected" + Test = { + $script = $commonPath + "6.3.3.12.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.13" + Task = "Ensure file deletion events by users are collected" + Test = { + $script = $commonPath + "6.3.3.13.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.14" + Task = "Ensure events that modify the system's Mandatory Access Controls are collected" + Test = { + $script = $commonPath + "6.3.3.14.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.15" + Task = "Ensure successful and unsuccessful attempts to use the chcon command are recorded" + Test = { + $script = $commonPath + "6.3.3.15.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.16" + Task = "Ensure successful and unsuccessful attempts to use the setfacl command are recorded" + Test = { + $script = $commonPath + "6.3.3.16.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.17" + Task = "Ensure successful and unsuccessful attempts to use the chacl command are recorded" + Test = { + $script = $commonPath + "6.3.3.17.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.18" + Task = "Ensure successful and unsuccessful attempts to use the usermod command are recorded" + Test = { + $script = $commonPath + "6.3.3.18.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.19" + Task = "Ensure kernel module loading unloading and modification is collected" + Test = { + $script = $commonPath + "6.3.3.19.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.20" + Task = "Ensure the audit configuration is immutable" + Test = { + $result1 = grep -Ph -- '^\h*-e\h+2\b' /etc/audit/rules.d/*.rules | tail -1 + if ($result1 -match "-e 2") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "6.3.3.21" + Task = "Ensure the running and on disk configuration is the same" + Test = { + $result1 = augenrules --check + if ($result1 -match "/usr/sbin/augenrules: No change") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "6.3.4.1" + Task = "Ensure the audit log file directory mode is configured" + Test = { + $script = $scriptPath + "6.3.4.1.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.2" + Task = "Ensure audit log files mode is configured" + Test = { + $script = $scriptPath + "6.3.4.2.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.3" + Task = "Ensure audit log files owner is configured" + Test = { + $script = $scriptPath + "6.3.4.3.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.4" + Task = "Ensure audit log files group owner is configured" + Test = { + $script = $scriptPath + "6.3.4.4.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.5" + Task = "Ensure audit configuration files mode is configured" + Test = { + $script = $commonPath + "6.3.4.5.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.6" + Task = "Ensure audit configuration files owner is configured" + Test = { + $script = $commonPath + "6.3.4.6.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.7" + Task = "Ensure audit configuration files group owner is configured" + Test = { + $script = $commonPath + "6.3.4.7.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.8" + Task = "Ensure audit tools mode is configured" + Test = { + $script = $commonPath + "6.3.4.8.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.9" + Task = "Ensure audit tools owner is configured" + Test = { + $script = $commonPath + "6.3.4.9.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.3.4.10" + Task = "Ensure audit tools group owner is configured" + Test = { + $test1 = stat -Lc '%G' /sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules | awk '$1 != "root" {print}' + if ($test1 -eq $null) { + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "7.1.1" + Task = "Ensure permissions on /etc/passwd are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/passwd- + if ($test1 -match "644 0/root 0/root") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "7.1.2" + Task = "Ensure permissions on /etc/passwd- are configured" + Test = { + $test1 = stat -c '%#a' /etc/passwd- | grep -q "0644" + if ($?) { + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "7.1.3" + Task = "Ensure permissions on /etc/group are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/group + if ($test1 -match "644 0/root 0/root") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "7.1.4" + Task = "Ensure permissions on /etc/group- are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/group- + if ($test1 -match "644 0/root 0/root") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "7.1.5" + Task = "Ensure permissions on /etc/shadow are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/shadow + if ($test1 -match "0 0/root 0/root") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "7.1.6" + Task = "Ensure permissions on /etc/shadow- are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/shadow- + if ($test1 -match "0 0/root 0/root") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "7.1.7" + Task = "Ensure permissions on /etc/gshadow are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/gshadow + if ($test1 -match "0 0/root 0/root") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "7.1.8" + Task = "Ensure permissions on /etc/gshadow- are configured" + Test = { + $test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/gshadow- + if ($test1 -match "0 0/root 0/root") { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "7.1.9" + Task = "Ensure permissions on /etc/shells are configured" + Test = { + $script = $commonPath + "7.1.9.sh" + bash $script + if ($?) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "7.1.10" + Task = "Ensure permissions on /etc/security/opasswd are configured" + Test = { + $script = $commonPath + "7.1.10.sh" + bash $script + if ($?) { + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "7.1.11" + Task = "Ensure world writable files and directories are secured" + Test = { + #$partitions = mapfile -t partitions < (sudo fdisk -l | grep -o '/dev/[^ ]*') + #$test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -0002 + $script = $commonPath + "7.1.11.sh" + bash $script + if ($?) { + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "7.1.12" + Task = "Ensure no files or directories without an owner and a group exist" + Test = { + $script = $commonPath + "7.1.12.sh" + bash $script + if ($?) { + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "7.1.13" + Task = "Ensure SUID and SGID files are reviewed" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -4000 + $message = "" + foreach ($line in $test1) { + $message += "
$line" + } + return @{ + Message = "Please review following list of files: $($message)" + Status = "None" + } + } +} + +[AuditTest] @{ + Id = "7.2.1" + Task = "Ensure accounts in /etc/passwd use shadowed passwords" + Test = { + $resultScript = $scriptPath + "7.2.1.sh" + $result = bash $resultScript + if ($result -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "7.2.2" + Task = "Ensure /etc/shadow password fields are not empty" + Test = { + $resultScript = $scriptPath + "7.2.2.sh" + $result = bash $resultScript + if ($result -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "7.2.3" + Task = "Ensure all groups in /etc/passwd exist in /etc/group" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + for i in $(cut -s -d: -f4 /etc/passwd | sort -u ); do + grep -q -P "^.*?:[^:]*:$i:" /etc/group + if [ $? -ne 0 ]; then + echo "Group $i is referenced by /etc/passwd but does not exist in /etc/group" + fi + done +} +'@ + $script = bash -c $script_string + if ($script -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "7.2.4" + Task = "Ensure no duplicate UIDs exist" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + cut -f3 -d":" /etc/passwd | sort -n | uniq -c | while read x ; do + [ -z "$x" ] && break + set - $x + if [ $1 -gt 1 ]; then + users=$(awk -F: '($3 == n) { print $1 }' n=$2 /etc/passwd | xargs) + echo "Duplicate UID ($2): $users" + fi + done +} +'@ + $script = bash -c $script_string + if ($script -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "7.2.5" + Task = "Ensure no duplicate GIDs exist" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + cut -d: -f3 /etc/group | sort | uniq -d | while read x ; do + echo "Duplicate GID ($x) in /etc/group" + done +} +'@ + $script = bash -c $script_string + if ($script -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "7.2.6" + Task = "Ensure no duplicate user names exist" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + cut -d: -f1 /etc/passwd | sort | uniq -d | while read -r x; do + echo "Duplicate login name $x in /etc/passwd" + done +} +'@ + $script = bash -c $script_string + if ($script -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "7.2.7" + Task = "Ensure no duplicate group names exist" + Test = { + $script_string = @' +#!/usr/bin/env bash +{ + cut -d: -f1 /etc/group | sort | uniq -d | while read -r x; do + echo "Duplicate group name $x in /etc/group" + done +} +'@ + $script = bash -c $script_string + if ($script -eq $null) { + return $retCompliant + } + else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ # in CIS it's automated, but in Excelsheet it's manual + Id = "7.2.8" + Task = "Ensure local interactive user home directories are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "7.2.9" + Task = "Ensure local interactive user dot files access is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + diff --git a/ATAPAuditor/AuditGroups/SBD - Application Control.ps1 b/ATAPAuditor/AuditGroups/SBD - Application Control.ps1 new file mode 100644 index 0000000..0c0dcca --- /dev/null +++ b/ATAPAuditor/AuditGroups/SBD - Application Control.ps1 @@ -0,0 +1,68 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +[AuditTest] @{ + Id = "SBD-501" + Task = "Ensure Windows Defender Application Control (WDAC) is available." + Test = { + # check newer than win10 + $osVersion = (Get-CimInstance Win32_OperatingSystem).Version + # check whether system is server version 16 or newer + $windowsServerVersions = @( + "Windows Server 2016", + "Windows Server 2019", + "Windows Server 2022" + ) + $isServer2016newer = $windowsServerVersions -contains $os + if( $osVersion -ge '10.0.0.0' -or $isServer2016newer -eq $true){ + return @{ + Message = "Your device supports WDAC." + Status = "True" + } + } + return @{ + Message = "Only supported on Windows 10 and newer, as well as Windows Server 2016 and newer." + Status = "None" + } + } +} +[AuditTest] @{ + Id = "SBD-502" + Task = "Ensure Windows Defender Application ID Service is running." + Test = { + try{ + if((Get-Service -Name APPIDSvc -ErrorAction Stop).Status -eq "Running"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "AppLocker is not running. Currently: $((Get-Service -Name APPIDSvc -ErrorAction Stop).Status)" + Status = "False" + } + } + catch [System.SystemException]{ + return @{ + Message = "Service not found!" + Status = "False" + } + } + } +} +# [AuditTest] @{ Check for executable rules - windows installer rules - script rules - packaged app rules +# Id = "SBD-042" +# Task = "Ensure Windows Defender Application ID Service is running." +# Test = { +# if((Get-Service -Name APPIDSvc).Status -eq "Running"){ +# return @{ +# Message = "Compliant" +# Status = "True" +# } +# } +# return @{ +# Message = "AppLocker is not running. Currently: $((Get-Service -Name APPIDSvc).Status)" +# Status = "False" +# } +# } +# } diff --git a/ATAPAuditor/AuditGroups/SBD - Connectivity Security.ps1 b/ATAPAuditor/AuditGroups/SBD - Connectivity Security.ps1 new file mode 100644 index 0000000..f56c520 --- /dev/null +++ b/ATAPAuditor/AuditGroups/SBD - Connectivity Security.ps1 @@ -0,0 +1,1434 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$listOfWeakCipherSuites = getListOfWeakCipherSuites +$listOfInsecureCipherSuites = getListOfInsecureCipherSuites +[AuditTest] @{ + Id = "SBD-401" + Task = "Ensure system is configured to deny remote access via Terminal Services." + Test = { + $value = (Get-ItemProperty -path "HKLM:\System\CurrentControlSet\Control\Terminal Server").fDenyTSConnections + if($value -eq 1){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "System is not configured to deny remote access via Terminal Services." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-402" + Task = "Ensure system is configured to prevent RDP service." + Test = { + $value = (Get-ItemProperty -path "HKLM:\System\CurrentControlSet\Control\Terminal Server").AllowRemoteRPC + if($value -eq 0){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "System is not configured to prevent RDP service." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-403" + Task = "Ensure NTLM Session Server Security settings are configured." + Test = { + $value = (Get-ItemProperty -path 'HKLM:\System\CurrentControlSet\Control\Lsa\MSV1_0').NtlmMinServerSec + if($value -eq 537395200){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "NTLM Session Server Security settings are configured. Currently: $($value)" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-404" + Task = "Ensure WinFW Service is running." + Test = { + try{ + $value = (Get-Service WinRM -ErrorAction Stop).status + if($value -eq "Running"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + catch [System.SystemException]{ + return @{ + Message = "Service not found!" + Status = "False" + } + } + return @{ + Message = "WinFW Service is not running. Currently: $($value)" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-405" + Task = "Ensure NetBIOS is set to 'Disabled' for all active Network cards." + Test = { + try{ + $networkCards = Get-WmiObject win32_networkadapterconfiguration -filter 'IPEnabled=true' | select Description, TcpipNetBIOSOptions + $nonCompliantCards = @() + + for($i = 0; $i -lt $networkCards.Count; $i++){ + if($networkCards[$i].TcpipNetBIOSOptions -ne 0){ + $nonCompliantCards += $networkCards[$i] + } + } + + if($nonCompliantCards.Count -eq 0){ + return @{ + Message = "Compliant" + Status = "True" + } + } + if($nonCompliantCards.Count -eq $networkCards.Count){ + return @{ + Message = "All network cards have NETBIOS enabled." + Status = "False" + } + } + $message = "Following network cards have NETBIOS enabled: " + $nonCompliantCards.Description + return @{ + Message = $message + Status = "Warning" + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Value not found." + Status = "Error" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Value not found." + Status = "Error" + } + } + } +} +[AuditTest] @{ + Id = "SBD-406" + Task = "Ensure SMBv1 is set to 'Disabled'." + Test = { + $value = (Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol).State + if($value -eq "Disabled"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "SMBv1 is Enabled." + Status = "False" + } + } +} + +[AuditTest] @{ + Id = "SBD-407" + Task = "Disable SSLv2 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-408" + Task = "Disable SSLv2 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-409" + Task = "Disable SSLv2 Protocol (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-410" + Task = "Disable SSLv2 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-411" + Task = "Disable SSLv3 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-412" + Task = "Disable SSLv3 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-413" + Task = "Disable SSLv3 Protocol (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-414" + Task = "Disable SSLv3 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-415" + Task = "Disable TLS1.0 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-416" + Task = "Disable TLS1.0 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-417" + Task = "Disable TLS1.0 Protocol (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-418" + Task = "Disable TLS1.0 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-419" + Task = "Disable TLS1.1 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-420" + Task = "Disable TLS1.1 Protocol (Server DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-421" + Task = "Disable TLS1.1 Protocol (Client)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-422" + Task = "Disable TLS1.1 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-423" + Task = "Enable TLS1.2 Protocol (Server)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -eq 4294967295) { + return @{ + Message = "The current registry value is '$regValue', which is no longer supported by Microsoft. For more information, please refer to this link:
"` + +'
'` + +'Learn.microsoft.com - TLS, DTLS, and SSL protocol version settings' + Status = "False" + } + } + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-424" + Task = "Enable TLS1.2 Protocol (Server Default)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-425" + Task = "Enable TLS1.2 Protocol (Client)" + Test = { + $OS = Get-CimInstance Win32_OperatingSystem | Select-Object Caption + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -eq 4294967295) { + return @{ + Message = "The current registry value is '$regValue', which is no longer supported by Microsoft. For more information, please refer to this link:
"` + +'
'` + +'Learn.microsoft.com - TLS, DTLS, and SSL protocol version settings' + Status = "False" + } + } + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + if($OS -match "Server 2022" -or $OS -match "Windows 11"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + if($OS -match "Server 2022" -or $OS -match "Windows 11"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-426" + Task = "Enable TLS1.2 Protocol (Client DisabledByDefault)" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" ` + -Name "DisabledByDefault" ` + | Select-Object -ExpandProperty "DisabledByDefault" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-427" + Task = "Disable NULL Cipher" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\NULL" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-428" + Task = "Disable DES Cipher Suite" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\DES 56/56" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-429" + Task = "Disable RC4 Cipher Suite - 40/128" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-430" + Task = "Disable RC4 Cipher Suite - 56/128" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-431" + Task = "Disable RC4 Cipher Suite - 64/128" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 64/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-432" + Task = "Disable RC4 Cipher Suite - 128/128" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-433" + Task = "Disable AES 128/128 Cipher Suite" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\AES 128/128" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-434" + Task = "Enable AES 256/256 Cipher Suite" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\AES 256/256" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -eq 4294967295) { + return @{ + Message = "The current registry value is '$regValue', which is no longer supported by Microsoft. For more information, please refer to this link:
"` + +'
'` + +'Learn.microsoft.com - TLS, DTLS, and SSL protocol version settings' + Status = "False" + } + } + if ($regValue -ne 1) { + return @{ + Message = "Registry value is '$regValue'. Expected: 1" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-435" + Task = "Disable Triple DES Cipher Suite" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\Triple DES 168" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-436" + Task = "Disable SHA-1 hash" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Hashes\SHA" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-437" + Task = "Disable MD5 hash" + Test = { + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Hashes\MD5" ` + -Name "Enabled" ` + | Select-Object -ExpandProperty "Enabled" + + if ($regValue -ne 0) { + return @{ + Message = "Registry value is '$regValue'. Expected: 0" + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + return @{ + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + return @{ + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-438" + Task = "Configure Cipher Suite Ordering" + Test = { + #check if correct type + $typeTable = @{ + "String" = "String Value" + "Byte" = "Byte Value" + "Int32" = "DWORD (32-bit) Value" + "Int64" = "QWORD (64-bit) Value" + "String[]" = "Multi-String Value" + } + #Default status + $status = "Error" + + #Output + $verbInsecure = "rules have" + $verbWeak = "rules have" + + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002" ` + -Name "Functions" + $reference = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" + $res = $regValue.Functions.GetType().Name + + + $currentType = $typeTable[$res] + if ($res -ne [String]) { + return @{ + Message = "Wrong Registry type! Registry type is '$currentType'. Expected: 'String Value'" + Status = "False" + } + } + + #check if insecure or weak cipher is inside value + $regValues = $regValue.Split(',') + $regValues = $regValues -replace ' ', '' + $weakRulesFound = @() + $insecureRulesFound = @() + foreach($element in $regValues){ + if($listOfWeakCipherSuites.Contains($element)){ + $weakRulesFound += $element + } + if($listOfInsecureCipherSuites.Contains($element)){ + $insecureRulesFound += $element + } + } + if($insecureRulesFound.Count -eq 1){$verbInsecure = "rule has"} + if($weakRulesFound.Count -eq 1){$verbWeak = "rule has"} + $insecureMessage = "$($insecureRulesFound.Count) insecure $($verbInsecure) been found! List of insecure rules:
" + $weakMessage = "$($weakRulesFound.Count) weak $($verbWeak) been found! List of weak rules:
" + + #Preparing message + foreach($member in $weakRulesFound){ + $status = "Warning" + $weakMessage += "$($member)
" + } + foreach($member in $insecureRulesFound){ + $status = "False" + $insecureMessage += "$($member)
" + } + #Combine or shorten message + if($insecureRulesFound.Count -gt 0 -or $weakRulesFound.Count -gt 0){ + $message = "" + if($weakRulesFound.Count -eq 0){ $weakMessage = "" } + if($insecureRulesFound.Count -eq 0){ $insecureMessage = "" } + + $message = $insecureMessage + $weakMessage + return @{ + Message = $message + Status = $status + } + } + } + catch { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002" ` + -Name "Functions" + $reference = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" + $res = $regValue.Functions.GetType().Name + + $currentType = $typeTable[$res] + if ($res -ne [String[]]) { + return @{ + Message = "Wrong Registry type! Registry type is '$currentType'. Expected: 'Multi-String Value'" + Status = "False" + } + } + + #check if insecure or weak cipher is inside value + $regValues = $regValue -replace ' ', '' + $weakRulesFound = @() + $insecureRulesFound = @() + foreach($element in $regValues){ + if($listOfWeakCipherSuites.Contains($element)){ + $weakRulesFound += $element + } + if($listOfInsecureCipherSuites.Contains($element)){ + $insecureRulesFound += $element + } + } + if($insecureRulesFound.Count -eq 1){$verbInsecure = "rule has"} + if($weakRulesFound.Count -eq 1){$verbWeak = "rule has"} + $insecureMessage = "$($insecureRulesFound.Count) insecure $($verbInsecure) been found! List of insecure rules:
" + $weakMessage = "$($weakRulesFound.Count) weak $($verbWeak) been found! List of weak rules:
" + + #Preparing message + foreach($member in $weakRulesFound){ + $status = "Warning" + $weakMessage += "$($member)
" + } + foreach($member in $insecureRulesFound){ + $status = "False" + $insecureMessage += "$($member)
" + } + #Combine or shorten message + if($insecureRulesFound.Count -gt 0 -or $weakRulesFound.Count -gt 0){ + $message = "" + if($weakRulesFound.Count -eq 0){ $weakMessage = "" } + if($insecureRulesFound.Count -eq 0){ $insecureMessage = "" } + + $message = $insecureMessage + $weakMessage + return @{ + Message = $message + Status = $status + } + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} diff --git a/ATAPAuditor/AuditGroups/SBD - Linux Base Security.ps1 b/ATAPAuditor/AuditGroups/SBD - Linux Base Security.ps1 new file mode 100644 index 0000000..8644305 --- /dev/null +++ b/ATAPAuditor/AuditGroups/SBD - Linux Base Security.ps1 @@ -0,0 +1,462 @@ +function getKernelVersion { + $vsplit = $(uname -r).split('-') + if ($vsplit[1] -match '\.') { # Fedora + $vsplit[1] = $vsplit[1].split('.')[0] + } + return [version]($vsplit[0] + '.' + $vsplit[1]) +} +function commandExists { + param ( + $command + ) + return [bool](Get-Command -Name $command -ErrorAction SilentlyContinue) +} +[AuditTest] @{ + Id = "DSBD-001" + Task = "Ensure the system is booting in UEFI mode." + Test = { + if (Test-Path -Path /sys/firmware/efi) { + $status = @{ + Message = "Compliant" + Status = "True" + } + } else { + $status = @{ + Message = "System is not booting using UEFI mode." + Status = "False" + } + } + return $status + } +} +[AuditTest] @{ + Id = "DSBD-002" + Task = "Ensure the system is using SecureBoot." + Test = { + if (Test-Path -Path /sys/firmware/efi) { + if ($(mokutil --sb-state) -eq "SecureBoot enabled") { + $status = @{ + Message = "Compliant" + Status = "True" + } + } else { + $status = @{ + Message = "System is not booting using UEFI mode." + Status = "False" + } + } + } else { + $status = @{ + Message = "SecureBoot is only supported on UEFI." + Status= "False" + } + } + return $status + } +} +[AuditTest] @{ + Id = "DSBD-003" + Task = "Ensure the system has a TPM Chip." + Test = { + if (Test-Path -Path /dev/tpm0) { # /dev/tpmrm0 is _only_ for TPM 2.0 + $status = @{ + Message = "Compliant" + Status = "True" + } + } else { + $status = @{ + Message = "Could not detect a TPM chip" + Status = "False" + } + } + return $status + } +} +[AuditTest] @{ + Id = "DSBD-004" + Task = "Ensure the TPM Chip is implementing specification version 2.0 or higher." + Test = { + if ($(getKernelVersion) -ge [version]'5.6.0.0') { # For Ubuntu 20.04 e.g. + $spec = [float](Get-Content -Path '/sys/class/tpm/tpm0/tpm_version_major') + } else { + $tpm2toolsMajorVersion = [int]($(tpm2_getcap -v) | Select-String -Pattern '^.+version=\"(\d)\..+$').Matches.Groups[1].Value + if ($tpm2toolsMajorVersion -le 3) { # old versions up to 3.x had a different syntax (Debian 9) + $text = $(tpm2_getcap -c properties-fixed) + $match = [regex]::matches($text, '(?smi)TPM_PT_FAMILY_INDICATOR: as UINT32: +0[xX][0-9a-fA-F]+ as string: +\"(\d\.\d)\"').Groups[1].Value + } else { # new versions 4.x (RHEL 8) + $text = $(tpm2_getcap properties-fixed) + $match = [regex]::matches($text, '(?smi)TPM2_PT_FAMILY_INDICATOR: raw: +0[xX][0-9a-fA-F]+ value: +\"(\d\.\d)\"').Groups[1].Value + } + $spec = [float]$match + } + + if ($spec -ge 2.0) { + return @{ + Message = "Compliant" + Status = "True" + } + } elseif ($spec -gt 0) { + return @{ + Message = "Specification version lower than 2.0 found." + Status = "Warning" + } + } else { + return @{ + Message = "No implemented specification version found." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "DSBD-005" + Task = "Report the count of local users on the system." + Test = { + # Linux native alternative: grep -c ^ /etc/passwd + $countUsers = (Get-Content /etc/passwd).Count + return @{ + Message = "System has $countUsers local users" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "DSBD-006" + Task = "Report the count of local interactive users on the system." + Test = { + $countUsers = (Get-Content /etc/passwd | Where-Object {-not ($_ -match "/usr/sbin/nologin" -or $_ -match "/bin/false" -or $_ -match "/bin/sync")}).Count + $status = switch ($countUsers) { + {($PSItem -ge 0) -and ($PSItem -le 2)}{ # 0, 1, 2 + @{ + Message = "Compliant" + Status = "True" + } + } + {($PSItem -gt 2) -and ($PSItem -le 5)}{ # 3, 4, 5 + @{ + Message = "System has 3-5 local users." + Status = "Warning" + } + } + {$PSItem -gt 5}{ # 6, ... + @{ + Message = "System has 6 or more local users." + Status = "False" + } + } + Default { + @{ + Message = "Cannot determine the count of local users" + Status = "Error" + } + } + } + return $status + } +} +[AuditTest] @{ + Id = "DSBD-007" + Task = "Get the count of admin users on the system." + Test = { + $usersSudo = ($(getent group sudo) -split ":")[3] + $usersRoot = ($(getent group root) -split ":")[3] + $usersWheel = ($(getent group wheel) -split ":")[3] + $usersAdmin = ($(getent group admin) -split ":")[3] + $usersAdm = ($(getent group adm) -split ":")[3] + $userIdZero = ($(getent passwd 0) -split ":")[0] + $allUsersArr = @($usersSudo, $usersRoot, $usersWheel, $usersAdmin, $usersAdm, $userIdZero) | Where-Object {$_ -ne "" -and $_ -ne $null} | Sort-Object | Get-Unique + $status = switch ($allUsersArr.Count) { + {($PSItem -ge 0) -and ($PSItem -le 2)}{ # 0, 1, 2 + @{ + Message = "Compliant" + Status = "True" + } + } + {($PSItem -gt 2) -and ($PSItem -le 5)}{ # 3, 4, 5 + @{ + Message = "System has 3-5 admin users." + Status = "Warning" + } + } + {$PSItem -gt 5}{ # 6, ... + @{ + Message = "System has 6 or more admin users." + Status = "False" + } + } + Default { + @{ + Message = "Cannot determine the count of admin users" + Status = "Error" + } + } + } + return $status + } +} +[AuditTest] @{ + Id = "DSBD-008" + Task = "Ensure the NX bit is set." + Test = { + $query = (-split (Get-Content /proc/cpuinfo | Where-Object {$_ -match '^flags.*$'} | Get-Unique)) -Contains 'nx' + if ($query) { + return @{ + Message = "Compliant" + Status = "True" + } + } else { + return @{ + Message = "The NX bit is not set." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "DSBD-009" + Task = "Ensure the ASLR is enabled." + Test = { + $query = [int](Get-Content /proc/sys/kernel/randomize_va_space) + if ($query -ge 2) { + return @{ + Message = "Compliant" + Status = "True" + } + } elseif ($query -eq 1) { + return @{ + Message = "ASLR is partially enabled." + Status = "Warning" + } + } else { + return @{ + Message = "ASLR is not enabled." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "DSBD-010" + Task = "Ensure AppArmor or SELinux is enabled." + Test = { + if (commandExists 'aa-status') { + $AppArmorStatus = ($(aa-status) -match '^apparmor module is loaded.*$').Count -gt 0 + } + if (commandExists 'getenforce') { + $SELinuxStatus = ($(getenforce) -match 'Enforcing$').Count -gt 0 + } + + if ($AppArmorStatus -or $SELinuxStatus) { + return @{ + Message = "Compliant" + Status = "True" + } + } else { + return @{ + Message = "Neither AppArmor nor SELinux are enabled." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "DSBD-011" + Task = "Ensure CPU has no known vulnerabilities." + Test = { + $query = ((Get-Content /sys/devices/system/cpu/vulnerabilities/*) -match '^Vulnerable.*$').Count + if ($query -eq 0) { + return @{ + Message = "Compliant" + Status = "True" + } + } else { + return @{ + Message = "System has $query known CPU vulnerabilities." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "DSBD-012" + Task = "Ensure root login using SSH is not permitted." + Test = { + $rootLoginDisabled = [bool](Get-Content /etc/ssh/sshd_config | Select-String -Pattern '^PermitRootLogin no').Matches.Length + if ($rootLoginDisabled) { + return @{ + Message = "Compliant" + Status = "True" + } + } else { + return @{ + Message = "Login for root using SSH is permitted." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "DSBD-013" + Task = "Ensure a firewall is installed (ufw, iptables, nftables)." + Test = { + if (commandExists dpkg) { + $ufwInstalled = [bool]($(dpkg -s ufw 2> /dev/zero) -match 'Status: install').Count + $iptablesInstalled = [bool]($(dpkg -s iptables 2> /dev/zero) -match 'Status: install').Count + $nftablesInstalled = [bool]($(dpkg -s nftables 2> /dev/zero) -match 'Status: install').Count + } + if (commandExists rpm) { + $ufwInstalled = [bool]($(rpm -qa) -match '^ufw.+$').Count + $iptablesInstalled = [bool]($(rpm -qa) -match '^iptables.+$').Count + $nftablesInstalled = [bool]($(rpm -qa) -match '^nftables.+$').Count + } + if ($ufwInstalled -or $iptablesInstalled -or $nftablesInstalled) { + return @{ + Message = "Compliant" + Status = "True" + } + } else { + return @{ + Message = "Login for root using SSH is permitted." + Status = "False" + } + } + } +} +function getFilePermissionsRegex { + Param( + [Parameter(Mandatory=$true)][String][ValidateNotNullOrEmpty()]$filePath + ) + $text = stat $filePath + $match = [regex]::matches($text, '\S+:\s+\((\d+)\/\S+\)\s+Uid:\s+\(\s*(\d+)\/\s+(\S+)\)\s+Gid:\s+\(\s+(\d+)\/\s+(\S+)\)') + return [ordered]@{ + permissionsOct = $match.Groups[1].Value + ownerUserId = $match.Groups[2].Value + ownerUserName = $match.Groups[3].Value + ownerGroupId = $match.Groups[4].Value + ownerGroupName = $match.Groups[5].Value + } +} +function checkFilePermissions { + Param( + [Parameter(Mandatory=$true)][String][ValidateNotNullOrEmpty()]$filePath, + [Parameter(Mandatory=$true)][String][ValidateNotNullOrEmpty()]$permissionsOct, + [Parameter(Mandatory=$true)][String][ValidateNotNullOrEmpty()]$ownerUserName, + [Parameter(Mandatory=$true)][String][ValidateNotNullOrEmpty()]$ownerGroupName + ) + # calculate mode + $item = Get-Item $filePath + $modeLowerBits = $item.UnixStat.Mode -band 4095 # 4095_(10) = 111111111111_(2) = 7777_(8) = FFF_(16) + $mode = [Convert]::ToString($modeLowerBits, 8) # Conversion not necessary in future: https://github.com/PowerShell/PowerShell/issues/16757 , alternative: stat -c '%a' /etc/passwd + # check for same or more restricted permissions + foreach ($i in 0..($mode.Length - 1)) { + if ($mode[$i] -gt $permissionsOct[$i]) { + return $false # = less restrictive + } + } + # check owning user and group + return $item.User -eq $ownerUserName -and $item.Group -eq $ownerGroupName +} +[AuditTest] @{ + Id = "DSBD-014" + Task = "Ensure /etc/passwd and /etc/passwd- have proper file permissions." + Test = { + $result = checkFilePermissions '/etc/passwd' '644' 'root' 'root' + if (Test-Path -Path '/etc/passwd-' -PathType Leaf) { + $result = $result -and (checkFilePermissions '/etc/passwd-' '644' 'root' 'root') + } + if ($result) { + return @{ + Message = "Compliant" + Status = "True" + } + } else { + return @{ + Message = "The file permissions are not set correctly." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "DSBD-015" + Task = "Ensure /etc/shadow and /etc/shadow- have proper file permissions." + Test = { + $result = (checkFilePermissions '/etc/shadow' '640' 'root' 'root') -or (checkFilePermissions '/etc/shadow' '640' 'root' 'shadow') + if (Test-Path -Path '/etc/shadow-' -PathType Leaf) { + $resultDash = (checkFilePermissions '/etc/shadow-' '640' 'root' 'root') -or (checkFilePermissions '/etc/shadow-' '640' 'root' 'shadow') + $result = $result -and $resultDash + } + if ($result) { + return @{ + Message = "Compliant" + Status = "True" + } + } else { + return @{ + Message = "The file permissions are not set correctly." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "DSBD-016" + Task = "Ensure /etc/group and /etc/group- have proper file permissions." + Test = { + $result = checkFilePermissions '/etc/group' '644' 'root' 'root' + if (Test-Path -Path '/etc/group-' -PathType Leaf) { + $result = $result -and (checkFilePermissions '/etc/group-' '644' 'root' 'root') + } + if ($result) { + return @{ + Message = "Compliant" + Status = "True" + } + } else { + return @{ + Message = "The file permissions are not set correctly." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "DSBD-017" + Task = "Ensure /etc/gshadow and /etc/gshadow- have proper file permissions." + Test = { + $result = (checkFilePermissions '/etc/gshadow' '640' 'root' 'root') -or (checkFilePermissions '/etc/gshadow' '640' 'root' 'shadow') + if (Test-Path -Path '/etc/gshadow-' -PathType Leaf) { + $resultDash = (checkFilePermissions '/etc/gshadow-' '640' 'root' 'root') -or (checkFilePermissions '/etc/gshadow-' '640' 'root' 'shadow') + $result = $result -and $resultDash + } + if ($result) { + return @{ + Message = "Compliant" + Status = "True" + } + } else { + return @{ + Message = "The file permissions are not set correctly." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "DSBD-018" + Task = "Ensure /etc/ssh/sshd_config has proper file permissions." + Test = { + $result = checkFilePermissions '/etc/ssh/sshd_config' '600' 'root' 'root' + if ($result) { + return @{ + Message = "Compliant" + Status = "True" + } + } else { + return @{ + Message = "The file permissions are not set correctly." + Status = "False" + } + } + } +} diff --git a/ATAPAuditor/AuditGroups/SBD - Platform Security.ps1 b/ATAPAuditor/AuditGroups/SBD - Platform Security.ps1 new file mode 100644 index 0000000..b0defa6 --- /dev/null +++ b/ATAPAuditor/AuditGroups/SBD - Platform Security.ps1 @@ -0,0 +1,569 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +[AuditTest] @{ + Id = "SBD-101" + Task = "Ensure the system is booting in 'UEFI' mode." + Test = { + if (isWindows8OrNewer) { + $status = switch ($env:firmware_type) { + "UEFI" { + @{ + Message = "Compliant" + Status = "True" + } + } + "Legacy" { + @{ + Message = "System is booting using 'Legacy' mode." + Status = "False" + } + } + Default { + @{ + Message = "Unknown boot mode" + Status = "False" + } + } + } + return $status + } + else { + if ((bcdedit | findstr -i path | findstr -i winload.efi).Count -ge 1) { + return @{ + Message = "Compliant" + Status = "True" + } + } + elseif (((bcdedit | findstr -i path | findstr -i winload.exe).Count -ge 1)) { + return @{ + Message = "System is booting using 'Legacy' mode." + Status = "False" + } + } + else { + return @{ + Message = "Unknown boot mode" + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "SBD-102" + Task = "Virtualization Based Security: Ensure the system is using SecureBoot." + Test = { + if (isWindows8OrNewer) { + try { + $status = switch ($env:firmware_type) { + "UEFI" { + $obj = Confirm-SecureBootUEFI + } + "Legacy" { + return @{ + Message = "System is booting using 'Legacy' mode. SecureBoot not supported." + Status = "False" + } + } + Default { + return @{ + Message = "Unknown boot mode" + Status = "False" + } + } + } + } + catch [UnauthorizedAccessException] { + return @{ + Message = "Permission Denied" + Status = "Error" + } + } + $status = switch ($obj) { + $true { + @{ + Message = "Compliant" + Status = "True" + } + } + $false { + @{ + Message = "SecureBoot is supported but disabled." + Status = "False" + } + } + Default { + @{ + Message = "SecureBoot is not supported or system is in non-UEFI mode." + Status = "False" + } + } + } + return $status + } + else { + return @{ + Message = "System does not support this feature (Windows 8 or newer required)." + Status = "None" + } + } + } +} +[AuditTest] @{ + Id = "SBD-103" + Task = "Ensure the TPM Chip is 'present'." + Test = { + $hasTpm = hasTPM + if (($null -eq $hasTpm) -or ($false -eq $hasTpm)) { + return @{ + Message = "No TPM Chip detected." + Status = "False" + } + } + if (isWindows8OrNewer) { + $obj = (Get-Tpm).TpmPresent + if ($obj -isnot [Boolean]) { + return @{ + Message = "Cannot get 'present' status of TPM." + Status = "Error" + } + } + $status = switch ($obj) { + $true { + @{ + Message = "Compliant" + Status = "True" + } + } + $false { + @{ + Message = "The TPM Chip is not 'present'." + Status = "False" + } + } + } + return $status + } + else { + # Get any property to see if a TPM is present + if (win7NoTPMChipDetected) { + return @{ + Message = "No TPM Chip detected." + Status = "False" + } + } else { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + } +} +[AuditTest] @{ + Id = "SBD-104" + Task = "Ensure the TPM Chip is 'ready'." + Test = { + $hasTpm = hasTPM + if (($null -eq $hasTpm) -or ($false -eq $hasTpm)) { + return @{ + Message = "No TPM Chip detected." + Status = "False" + } + } + if (isWindows8OrNewer) { + $obj = (Get-Tpm).TpmReady + if ($obj -isnot [Boolean]) { + return @{ + Message = "Cannot get 'ready' status of TPM." + Status = "Error" + } + } + $status = switch ($obj) { + $true { + @{ + Message = "Compliant" + Status = "True" + } + } + $false { + @{ + Message = "The TPM Chip is not 'ready'." + Status = "False" + } + } + } + return $status + } + else { + if (win7NoTPMChipDetected) { + return @{ + Message = "No TPM Chip detected." + Status = "False" + } + } else { + return @{ + Message = "System does not expose a 'ready' status" + Status = "None" + } + } + } + } +} +[AuditTest] @{ + Id = "SBD-105" + Task = "Ensure the TPM Chip is 'enabled'." + Test = { + $hasTpm = hasTPM + if (($null -eq $hasTpm) -or ($false -eq $hasTpm)) { + return @{ + Message = "No TPM Chip detected." + Status = "False" + } + } + if (isWindows8OrNewer) { + + $state = Get-WmiObject -class Win32_Tpm -namespace root\CIMV2\Security\MicrosoftTpm + if ($state.IsEnabled_InitialValue -eq $true) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "The TPM Chip is not 'enabled'." + Status = "False" + } + } + else { + if (win7NoTPMChipDetected) { + return @{ + Message = "No TPM Chip detected." + Status = "False" + } + } + if (Get-CimInstance -ClassName Win32_Tpm -Namespace root\cimv2\security\microsofttpm | Select-Object -ExpandProperty IsEnabled_InitialValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + else { + return @{ + Message = "The TPM Chip is not 'enabled'." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "SBD-106" + Task = "Ensure the TPM Chip is 'activated'." + Test = { + $hasTpm = hasTPM + if (($null -eq $hasTpm) -or ($false -eq $hasTpm)) { + return @{ + Message = "No TPM Chip detected." + Status = "False" + } + } + if (isWindows8OrNewer) { + $state = Get-WmiObject -class Win32_Tpm -namespace root\CIMV2\Security\MicrosoftTpm + if ($state.IsActivated_InitialValue -eq $true) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "The TPM Chip is not 'enabled'." + Status = "False" + } + } + else { + if (win7NoTPMChipDetected) { + return @{ + Message = "No TPM Chip detected." + Status = "False" + } + } + if (Get-CimInstance -ClassName Win32_Tpm -Namespace root\cimv2\security\microsofttpm | Select-Object -ExpandProperty IsActivated_InitialValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + else { + return @{ + Message = "The TPM Chip is not 'activated'." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "SBD-107" + Task = "Ensure the TPM Chip is 'owned'." + Test = { + $hasTpm = hasTPM + if (($null -eq $hasTpm) -or ($false -eq $hasTpm)) { + return @{ + Message = "No TPM Chip detected." + Status = "False" + } + } + if (isWindows8OrNewer) { + $state = Get-WmiObject -class Win32_Tpm -namespace root\CIMV2\Security\MicrosoftTpm + if ($state.IsOwned_InitialValue -eq $true) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "The TPM Chip is not 'enabled'." + Status = "False" + } + } + else { + if (win7NoTPMChipDetected) { + return @{ + Message = "No TPM Chip detected." + Status = "False" + } + } + if (Get-CimInstance -ClassName Win32_Tpm -Namespace root\cimv2\security\microsofttpm | Select-Object -ExpandProperty IsOwned_InitialValue) { + return @{ + Message = "Compliant" + Status = "True" + } + } + else { + return @{ + Message = "The TPM Chip is not 'owned'." + Status = "False" + } + } + + } + } +} +[AuditTest] @{ + Id = "SBD-108" + Task = "Ensure the TPM Chip is implementing specification version 2.0 or higher." + Test = { + $hasTpm = hasTPM + if (($null -eq $hasTpm) -or ($false -eq $hasTpm)) { + return @{ + Message = "No TPM Chip detected." + Status = "False" + } + } + # get array of implemented spec versions + $obj = (Get-CimInstance -Class Win32_Tpm -Namespace root\CIMV2\Security\MicrosoftTpm -ErrorAction SilentlyContinue | Select-Object -ExpandProperty SpecVersion) + if ($obj -eq $null) { + return @{ + Message = "No TPM Chip detected." + Status = "False" + } + } + # get main spec version (first element) + $obj = $obj.split(', ')[0] + + if ($obj -ge 2.0) { + return @{ + Message = "Compliant" + Status = "True" + } + } + elseif ($obj -gt 0) { + return @{ + Message = "Specification version lower than 2.0 found." + Status = "Warning" + } + } else { + return @{ + Message = "No implemented specification version found." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "SBD-109" + Task = "Virtualization Based Security: Ensure Virtualization Based Security is enabled and running." + Test = { + $isWindows10OrNewer = isWindows10OrNewer + if($isWindows10OrNewer -eq $false){ + return @{ + Message = "System does not support this feature (Windows 10 or newer required)." + Status = "None" + } + } + $obj = (Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard).VirtualizationBasedSecurityStatus + $status = switch ($obj) { + {$PSItem -eq 2} { + return @{ + Message = "Compliant" + Status = "True" + } + } + {$PSItem -eq 1} { + return @{ + Message = "VBS is activated but not running." + Status = "False" + } + } + {$PSItem -eq 0} { + return @{ + Message = "VBS is not activated." + Status = "False" + } + } + default { + return @{ + Message = "Cannot get the VBS status." + Status = "Error" + } + } + } + return $status + } +} +[AuditTest] @{ + Id = "SBD-110" + Task = "Virtualization Based Security: Ensure Hypervisor-protected Code Integrity (HVCI) is running." + Test = { + $isWindows10OrNewer = isWindows10OrNewer + if($isWindows10OrNewer -eq $false){ + return @{ + Message = "System does not support this feature (Windows 10 or newer required)." + Status = "None" + } + } + if ((Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard).SecurityServicesRunning -contains 2) { + return @{ + Message = "Compliant" + Status = "True" + } + } + else { + return @{ + Message = "HVCI is not running." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "SBD-111" + Task = "Virtualization Based Security: Ensure Credential Guard is running." + Test = { + $value = isWindows10OrNewer + if($value -eq $false){ + return @{ + Message = "System does not support this feature (Windows 10 or newer required)." + Status = "None" + } + } + $systemSKU = (Get-CimInstance Win32_OperatingSystem).Caption + $supportedSKUs = @("Windows Enterprise", "Windows Education", "Windows Server") + + $system = $systemSKU -replace "\d\s*", "" + $system = $system -replace "Microsoft ", "" + if($supportedSKUs.Contains($system)){ + if ((Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard).SecurityServicesRunning -contains 1) { + return @{ + Message = "Compliant" + Status = "True" + } + } + else { + return @{ + Message = "Credential Guard is not running." + Status = "False" + } + } + } + else{ + if ((Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard).SecurityServicesConfigured -contains 1) { + return @{ + Message = "Credential Guard is configured but not running, due to incompatibility with $($systemSKU)
See Microsoft documentation for further information:
Here" + Status = "False" + } + } + else { + return @{ + Message = "Credential Guard is not configured." + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "SBD-112" + Task = "Virtualization Based Security: Ensure Security Services are running." + Test = { + $value = isWindows10OrNewer + if($value -eq $false){ + return @{ + Message = "System does not support this feature (Windows 10 or newer required)." + Status = "None" + } + } + $serviceRunningIDs = (Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard).SecurityServicesRunning + if ($serviceRunningIDs -contains 0) { + return @{ + Message = "No Device Guard security services are running." + Status = "False" + } + } + if ($serviceRunningIDs -contains 1) { + $message += "Credential Guard" + } + if ($serviceRunningIDs -contains 2) { + if (![string]::IsNullOrEmpty($message)) { + $message += ", " + } + $message += "Memory Integrity (HVCI)" + } + if ($serviceRunningIDs -contains 3) { + if (![string]::IsNullOrEmpty($message)) { + $message += ", " + } + $message += "System Guard Secure Launch" + } + if ($serviceRunningIDs -contains 4) { + if (![string]::IsNullOrEmpty($message)) { + $message += ", " + } + $message += "SMM Firmware Measurement" + } + if ($serviceRunningIDs -contains 5) { + if (![string]::IsNullOrEmpty($message)) { + $message += ", " + } + $message += "Kernel-mode Hardware-enforced Stack Protection" + } + if ($serviceRunningIDs -contains 6) { + if (![string]::IsNullOrEmpty($message)) { + $message += ", " + } + $message += "Kernel-mode Hardware-enforced Stack Protection is configured in Audit mode" + } + if ($serviceRunningIDs -contains 7) { + if (![string]::IsNullOrEmpty($message)) { + $message += ", " + } + $message += "Hypervisor-Enforced Paging Translation" + } + return @{ + Message = "$message are running on Device Guard as services." + Status = "True" + } + } +} \ No newline at end of file diff --git a/ATAPAuditor/AuditGroups/SBD - PowerShell Security.ps1 b/ATAPAuditor/AuditGroups/SBD - PowerShell Security.ps1 new file mode 100644 index 0000000..6aebf35 --- /dev/null +++ b/ATAPAuditor/AuditGroups/SBD - PowerShell Security.ps1 @@ -0,0 +1,204 @@ +[AuditTest] @{ + Id = "SBD-301" + Task = "Ensure PowerShell Version is set to version 5 or higher." + Test = { + if ($PSVersionTable.PSVersion.Major -ge 5) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "PowerShell version is lower than 5. Current Version: $($PSVersionTable.PSVersion)" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-302" + Task = "Ensure PowerShell Version 2 is uninstalled." + Test = { + $ps2Found = $false + $messages = "The following PS2-related features are enabled:" + + $PSV2State = (Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2).State + if ($PSV2State -eq "Enabled") { + $messages += "
Windows PowerShell 2.0 Engine" + $ps2Found = $true + } + + $os = Get-CimInstance Win32_OperatingSystem + if ($os.ProductType -eq 1) { + $PSRootState = (Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root).State + if ($PSRootState -eq "Enabled") { + $messages += "
Windows PowerShell 2.0" + $ps2Found = $true + } + } + + if ($ps2Found -eq $true) { + return @{ + Message = $messages + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "SBD-303" + Task = "Ensure PowerShell is set to configured to use Constrained Language." + Test = { + $languageMode = $ExecutionContext.SessionState.LanguageMode + if($languageMode -eq "ConstrainedLanguage"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Language Mode is not set to 'Constrained Language'. Current configuration: $($languageMode)" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-304" + Task = "Ensure Execution policy is set to AllSigned / RemoteSigned." + Test = { + $execPolicy = Get-ExecutionPolicy + if($execPolicy -eq "AllSigned" -or $execPolicy -eq "RemoteSigned"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Execution Policy is not set to AllSigned / Remote Signed. Current configuration: $($execPolicy)" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-305" + Task = "Ensure PowerShell Commandline Audting is set to 'Enabled'." + Test = { + $value = (Get-ItemProperty -path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit' -ErrorAction SilentlyContinue).ProcessCreationIncludeCmdLine_Enabled + if($value -eq 1){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "PowerShell Commandline Auditing is not set to 'Enabled'." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-306" + Task = "Ensure PowerShell Module Logging is set to 'Enabled'." + Test = { + $value = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging' -ErrorAction SilentlyContinue).EnableModuleLogging + if($value -eq 1){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "PowerShell Module Logging is not set to 'Enabled'." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-307" + Task = "Ensure PowerShell ScriptBlockLogging is set to 'Enabled'." + Test = { + $value = (Get-ItemProperty -path 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -ErrorAction SilentlyContinue).EnableScriptBlockLogging + if($value -eq 1){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "PowerShell ScriptBlockLogging is not set to 'Enabled'." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-308" + Task = "Ensure PowerShell ScriptBlockInvocationLogging is set to 'Enabled'." + Test = { + $value = (Get-ItemProperty -path 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -ErrorAction SilentlyContinue).EnableScriptBlockInvocationLogging + if($value -eq 1){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "PowerShell ScriptBlockInvocationLogging is not set to 'Enabled'." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-309" + Task = "Ensure PowerShell Transcripting is set to 'Enabled'." + Test = { + $value = (Get-ItemProperty -path 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription' -ErrorAction SilentlyContinue).EnableTranscripting + if($value -eq 1){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "PowerShell Transcripting is not set to 'Enabled'." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-310" + Task = "Ensure PowerShell InvocationHeader is set to 'Enabled'." + Test = { + $value = (Get-ItemProperty -path 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription' -ErrorAction SilentlyContinue).EnableInvocationHeader + if($value -eq 1){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "PowerShell InvocationHeader is not set to 'Enabled'." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-311" + Task = "Ensure PowerShell ProtectedEventLogging is set to 'Enabled'." + Test = { + $value = (Get-ItemProperty -path 'HKLM:\Software\Policies\Microsoft\Windows\EventLog\ProtectedEventLogging' -ErrorAction SilentlyContinue).EnableProtectedEventLogging + if($value -eq 1){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "PowerShell ProtectedEventLogging is not set to 'Enabled'." + Status = "False" + } + } +} diff --git a/ATAPAuditor/AuditGroups/SBD - Windows Base Security.ps1 b/ATAPAuditor/AuditGroups/SBD - Windows Base Security.ps1 new file mode 100644 index 0000000..1a8f0e6 --- /dev/null +++ b/ATAPAuditor/AuditGroups/SBD - Windows Base Security.ps1 @@ -0,0 +1,622 @@ +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" + +[AuditTest] @{ + Id = "SBD-201" + Task = "Get License status." + Test = { + $lcStatus = Get-LicenseStatus $SkipLicenseCheck + if ($lcStatus -eq "Licensed") { + return @{ + Message = "Compliant" + Status = "True" + } + } + if ($lcStatus -eq "License check has been skipped.") { + return @{ + Message = $lcStatus + Status = "None" + } + } + return @{ + Message = "System not licensed." + Status = "False" + } + } +} +[AuditTest] @{ + Id = "SBD-202" + Task = "Get amount of active local users on system. (0 - 2: True; 3 - 5: Warning; 6 or higher: False)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Standalone Workstation", "Member Workstation", "Standalone Server", "Member Server" } + ) + Test = { + $users = Get-LocalUser; + $amountOfActiveUser = 0; + foreach ($user in $users) { + if ($user.Enabled -eq $True) { + $amountOfActiveUser ++; + } + } + $status = switch ((Get-LocalUser).Count) { + { ($amountOfActiveUser -ge 0) -and ($amountOfActiveUser -le 2) } { + # 0, 1, 2 + @{ + Message = "Compliant" + Status = "True" + } + } + { ($amountOfActiveUser -gt 2) -and ($amountOfActiveUser -le 5) } { + # 3, 4, 5 + @{ + Message = "System has $($amountOfActiveUser) local users." + Status = "Warning" + } + } + { $amountOfActiveUser -gt 5 } { + # 6, ... + @{ + Message = "System has 6 or more local users. (Currently $($amountOfActiveUser) users.)" + Status = "False" + } + } + Default { + @{ + Message = "Cannot determine the count of local users" + Status = "Error" + } + } + } + return $status + } +} +[AuditTest] @{ + Id = "SBD-203" + Task = "Get amount of users and groups in administrators group on system. (0 - 2: True; 3 - 5: Warning; 6 or higher: False)" + Constraints = @( + @{ "Property" = "DomainRole"; "Values" = "Standalone Workstation", "Member Workstation", "Standalone Server", "Member Server" } + ) + Test = { + try { + #List all groups + function Get-ADAdminCount($groupname) { + try { + $domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() + $root = $domain.GetDirectoryEntry() + $searcher = New-Object System.DirectoryServices.DirectorySearcher($root) + $searcher.Filter = "(&(objectCategory=group)(cn=$groupName))" + $group = $searcher.FindOne() + $groupDN = $group.Properties["distinguishedname"][0] + $searcher.Filter = "(&(objectCategory=user)(memberOf=$groupDN))" + $members = $searcher.FindAll() + return ($members | ForEach-Object { $_.Properties["distinguishedname"] }).Count + } + catch { + return 1 + } + } + + $allgroups = Get-LocalGroup -SID "S-1-5-32-544" | Get-LocalGroupMember + [int]$ADCount = 0 + [int]$localCount = 0 + foreach ($entry in $allgroups) { + if ($entry.PrincipalSource -eq "ActiveDirectory") { + $group = $entry.Name -split '\\' | Select-Object -Last 1 + $ADCount += Get-ADAdminCount $group + continue; + } + # only applies to Local Groups + $group = $entry.Name -split '\\' | Select-Object -Last 1 + try { + $localCount += (Get-LocalGroupMember $group -ErrorAction Stop).Count + } + catch [Microsoft.PowerShell.Commands.NotFoundException] { + $localCount++; + } + } + [int]$amountOfUserAndGroups = $ADCount + $localCount + $status = switch ($amountOfUserAndGroups) { + { ($amountOfUserAndGroups -ge 0) -and ($amountOfUserAndGroups -le 2) } { + # 0, 1, 2 + @{ + Message = "Total amount of users: $amountOfUserAndGroups
Amount of local users: $localCount
Amount of domain users: $ADCount
" + Status = "True" + } + } + { ($amountOfUserAndGroups -gt 2) -and ($amountOfUserAndGroups -le 5) } { + # 3, 4, 5 + @{ + Message = "Total amount of users: $amountOfUserAndGroups
Amount of local users: $localCount
Amount of domain users: $ADCount
" + Status = "Warning" + } + } + { $amountOfUserAndGroups -gt 5 } { + # 6, ... + @{ + Message = "Total amount of users: $amountOfUserAndGroups
Amount of local users: $localCount
Amount of domain users: $ADCount
" + Status = "False" + } + } + Default { + @{ + Message = "Cannot determine the count of admin users. Please check manually." + Status = "Error" + } + } + } + return $status + } + catch { + @{ + Message = "Cannot determine the count of admin users. Please check manually." + Status = "Error" + } + } + return $status + } +} +[AuditTest] @{ + Id = "SBD-204" + Task = "Ensure the status of the Bitlocker service is 'Running'." + Test = { + if (isWindows8OrNewer) { + if ((Get-WindowsOptionalFeature -Online -FeatureName Bitlocker).State -eq 'Disabled') { + return @{ + Message = "Bitlocker feature is not installed." + Status = "False" + } + } + } + $status = switch ((Get-Service BDESVC -ErrorAction SilentlyContinue).Status) { + "Running" { + @{ + Message = "Compliant" + Status = "True" + } + } + Default { + @{ + Message = "Bitlocker service is not 'Running'." + Status = "False" + } + } + } + return $status + } +} +[AuditTest] @{ + Id = "SBD-205" + Task = "Ensure that Bitlocker is activated on all volumes." + Test = { + try { + if (isWindows8OrNewer) { + if ((Get-WindowsOptionalFeature -Online -FeatureName Bitlocker).State -eq 'Disabled') { + return @{ + Message = "Bitlocker feature is not installed." + Status = "False" + } + } + $volumes = (Get-Bitlockervolume -ErrorAction Stop).Count + $volumes_fullenc = (Get-Bitlockervolume | Where-Object { $_.VolumeStatus -eq "FullyEncrypted" }).Count + } + else { + $volumes = (Get-CimInstance -Class Win32_EncryptableVolume -namespace Root\CIMV2\Security\MicrosoftVolumeEncryption | Measure-Object).Count + $volumes_fullenc = (Get-CimInstance -Class Win32_EncryptableVolume -namespace Root\CIMV2\Security\MicrosoftVolumeEncryption | Where-Object { $_.ProtectionStatus -eq 1 } | Measure-Object).Count + } + } + catch [System.Runtime.InteropServices.COMException] { + return @{ + Message = "Bitlocker status is unknown." + Status = "Error" + } + } + if ($volumes -lt 1) { + return @{ + Message = "Bitlocker status is unknown." + Status = "Error" + } + } + $enc_ratio = $volumes_fullenc / $volumes + $status = switch ($enc_ratio) { + { $enc_ratio -ge 1 } { + @{ + Message = "Compliant" + Status = "True" + } + } + { $enc_ratio -lt 1 } { + @{ + Message = "Bitlocker is not activated on all volumes." + Status = "False" + } + } + Default { + @{ + Message = "Bitlocker status is unknown." + Status = "Error" + } + } + } + return $status + } +} +[AuditTest] @{ + Id = "SBD-206" + Task = "Ensure the status of the Windows Defender service is 'Running'." + Test = { + try { + $status = switch ((Get-Service WinDefend -ErrorAction Stop).Status) { + "Running" { + @{ + Message = "Compliant" + Status = "True" + } + } + default { + @{ + Message = "Service is not 'Running'." + Status = "False" + } + } + } + return $status + } + catch [Microsoft.PowerShell.Commands.ServiceCommandException] { + return @{ + Message = "Current version is not supported." + Status = "None" + } + } + } +} +[AuditTest] @{ + Id = "SBD-207" + Task = "Ensure Windows Defender Application Guard is enabled." + Test = { + $isWindows10OrNewer = isWindows10OrNewer + if ($isWindows10OrNewer -eq $false) { + return @{ + Message = "System does not support this feature (Windows 10 or newer required)." + Status = "None" + } + } + $state = (Get-WindowsOptionalFeature -Online -FeatureName Windows-Defender-ApplicationGuard).State + if ($state -eq 'Enabled') { + return @{ + Message = "Compliant" + Status = "True" + } + } + else { + return @{ + Message = "Windows Defender Application Guard is not enabled." + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "SBD-208" + Task = "Ensure the Windows Firewall is enabled on all profiles." + Test = { + if (isWindows8OrNewer) { + if ((Get-NetFirewallProfile | Where-Object { $_.Enabled -eq 'False' } | Measure-Object).Count -gt 0) { + return @{ + Message = "Firewall is not enabled on all profiles" + Status = "False" + } + } + else { + return @{ + Message = "Compliant" + Status = "True" + } + } + } + else { + $fw = New-Object -ComObject hnetcfg.fwpolicy2 + $domain = $fw.FireWallEnabled(1) + $private = $fw.FireWallEnabled(2) + $public = $fw.FireWallEnabled(4) + if ($domain -and $private -and $public) { + return @{ + Message = "Compliant" + Status = "True" + } + } + else { + return @{ + Message = "Firewall is not enabled on all profiles" + Status = "False" + } + } + } + } +} +[AuditTest] @{ + Id = "SBD-209" + Task = "Check if the last successful search for updates was in the past 24 hours." + Test = { + try { + $startdate = (New-Object -com "Microsoft.Update.AutoUpdate").Results.LastSearchSuccessDate + if ($null -eq $startdate) { + return @{ + Message = "There was no search found." + Status = "False" + } + } + $tdiff = New-TimeSpan -ErrorAction Stop -Start $startdate -End (Get-Date) + $status = switch ($tdiff.Hours) { + { ($PSItem -ge 0) -and ($PSItem -le 24) } { + @{ + Message = "Compliant" + Status = "True" + } + } + { ($PSItem -gt 24) -and ($PSItem -le 24 * 5) } { + @{ + Message = "Last search for updates was within 5 days." + Status = "Warning" + } + } + Default { + @{ + Message = "Last search for updates was more than 5 days ago." + Status = "False" + } + } + } + return $status + } + catch { + return @{ + Message = "Not supported on this system." + Status = "None" + } + } + } +} +[AuditTest] @{ + Id = "SBD-210" + Task = "Check if the last successful installation of updates was in the past 5 days." # Windows defender definitions do count as updates + Test = { + try { + $startdateObjects = get-wmiobject -class win32_quickfixengineering | Sort-Object -Property InstalledOn -Descending -ErrorAction Stop + $startdate = $startdateObjects[0].InstalledOn + if ($null -eq $startdate) { + $startdate = (New-Object -com "Microsoft.Update.AutoUpdate").Results.LastInstallationSuccessDate + } + if ($null -eq $startdate) { + return @{ + Message = "There was no date found." + Status = "False" + } + } + $tdiff = New-TimeSpan -Start $startdate -End (Get-Date) + if ($tdiff.Days -ge 5) { + return @{ + Message = "Compliant" + Status = "True" + } + } + else { + $status = switch ($tdiff.Hours) { + { ($PSItem -ge 0) -and ($PSItem -le 24 * 5) } { + return @{ + Message = "Compliant" + Status = "True" + } + } + { ($PSItem -gt 24 * 5) -and ($PSItem -le 24 * 31) } { + return @{ + Message = "Last installation of updates was within the last month." + Status = "Warning" + } + } + Default { + return @{ + Message = "Last installation of updates was more than a month ago." + Status = "False" + } + } + } + } + return $status + } + catch [System.Management.Automation.GetValueInvocationException] { + return @{ + Message = "Your device needs to restart to install updates" + Status = "None" + } + } + catch { + return @{ + Message = "Not supported on this system." + Status = "None" + } + } + } +} +### SBD - 211 Placeholder +### SBD - 212 Placeholder +### SBD - 213 Placeholder +[AuditTest] @{ + Id = "SBD-214" + Task = "Ensure Attack Surface Reduction (ASR) rules are enabled." + Test = { + if (isWindows10OrNewer) { + $ruleids = (Get-MpPreference).AttackSurfaceReductionRules_Ids + $ruleactions = (Get-MpPreference).AttackSurfaceReductionRules_Actions + $RuleTable = for ($i = 0; $i -lt $ruleids.Count; $i++) { + [PSCustomObject]@{ + RuleId = $ruleids[$i] + RuleAction = $ruleactions[$i] + } + } + $countEnabled = ($RuleTable | Where-Object { $_.RuleAction -eq 1 } | Measure-Object).Count + + $status = switch ($countEnabled) { + { $PSItem -ge 12 } { + @{ + Message = "Compliant ($($countEnabled) rules enabled). For more information on ASR rules, check corresponding benchmarks." + Status = "True" + } + } + { ($PSItem -ge 1) -and ($PSItem -lt 12) } { + @{ + Message = "$($countEnabled) ASR rules are activated. For more information on ASR rules, check corresponding benchmarks." + Status = "Warning" + } + } + Default { + @{ + Message = "ASR rules are not enabled." + Status = "False" + } + } + } + return $status + } + else { + $windefrunning = CheckWindefRunning + if ((-not $windefrunning)) { + return @{ + Message = "This rule requires Windows Defender Antivirus to be enabled." + Status = "None" + } + } + $countEnabled = 0 + $Rule1 = @{ + Path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR" + Value = "ExploitGuard_ASR_Rules" + }; + $bool = $($Rule1.Path1), $($Rule1.Path2) | Test-MultiplePaths -Key $($Rule1.Value) -ExpectedValue 1 + if ($bool.Status -eq "True") { + $countEnabled++; + } + $Rule2 = @{ + Path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Value = "26190899-1602-49e8-8b27-eb1d0a1ce869" + }; + $bool = $($Rule2.Path1), $($Rule2.Path2) | Test-MultiplePaths -Key $($Rule2.Value) -ExpectedValue 1 + if ($bool.Status -eq "True") { + $countEnabled++; + } + $Rule3 = @{ + Path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Value = "3b576869-a4ec-4529-8536-b80a7769e899" + }; + $bool = $($Rule3.Path1), $($Rule3.Path2) | Test-MultiplePaths -Key $($Rule3.Value) -ExpectedValue 1 + if ($bool.Status -eq "True") { + $countEnabled++; + } + $Rule4 = @{ + Path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Value = "5beb7efe-fd9a-4556-801d-275e5ffc04cc" + }; + $bool = $($Rule4.Path1), $($Rule4.Path2) | Test-MultiplePaths -Key $($Rule4.Value) -ExpectedValue 1 + if ($bool.Status -eq "True") { + $countEnabled++; + } + $Rule5 = @{ + Path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Value = "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" + }; + $bool = $($Rule5.Path1), $($Rule5.Path2) | Test-MultiplePaths -Key $($Rule5.Value) -ExpectedValue 1 + if ($bool.Status -eq "True") { + $countEnabled++; + } + $Rule6 = @{ + Path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Value = "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" + }; + $bool = $($Rule6.Path1), $($Rule6.Path2) | Test-MultiplePaths -Key $($Rule6.Value) -ExpectedValue 1 + if ($bool.Status -eq "True") { + $countEnabled++; + } + $Rule7 = @{ + Path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Value = "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" + }; + $bool = $($Rule7.Path1), $($Rule7.Path2) | Test-MultiplePaths -Key $($Rule7.Value) -ExpectedValue 1 + if ($bool.Status -eq "True") { + $countEnabled++; + } + $Rule8 = @{ + Path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Value = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" + }; + $bool = $($Rule8.Path1), $($Rule8.Path2) | Test-MultiplePaths -Key $($Rule8.Value) -ExpectedValue 1 + if ($bool.Status -eq "True") { + $countEnabled++; + } + $Rule9 = @{ + Path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Value = "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" + }; + $bool = $($Rule9.Path1), $($Rule9.Path2) | Test-MultiplePaths -Key $($Rule9.Value) -ExpectedValue 1 + if ($bool.Status -eq "True") { + $countEnabled++; + } + $Rule10 = @{ + Path1 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Path2 = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules" + Value = "56a863a9-875e-4185-98a7-b882c64b5ce5" + }; + $bool = $($Rule10.Path1), $($Rule10.Path2) | Test-MultiplePaths -Key $($Rule10.Value) -ExpectedValue 1 + if ($bool.Status -eq "True") { + $countEnabled++; + } + + $status = switch ($countEnabled) { + { $PSItem -ge 10 } { + @{ + Message = "Compliant ($($countEnabled) rules enabled). For more information on ASR rules, check corresponding benchmarks." + Status = "True" + } + } + { ($PSItem -ge 1) -and ($PSItem -lt 10) } { + @{ + Message = "$($countEnabled) ASR rules are activated. For more information on ASR rules, check corresponding benchmarks." + Status = "Warning" + } + } + Default { + @{ + Message = "ASR rules are not enabled." + Status = "False" + } + } + } + + return $status + } + } +} +[AuditTest] @{ + Id = "SBD-215" + Task = "Ensure system is on 64-bit version" + Test = { + $is64bit = [Environment]::Is64BitOperatingSystem + if ($is64bit -eq $True) { + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "System not 64bit." + Status = "False" + } + } +} diff --git a/ATAPAuditor/AuditGroups/SUSE Linux Enterprise 15-CIS-1.1.1.ps1 b/ATAPAuditor/AuditGroups/SUSE Linux Enterprise 15-CIS-1.1.1.ps1 new file mode 100644 index 0000000..27929d7 --- /dev/null +++ b/ATAPAuditor/AuditGroups/SUSE Linux Enterprise 15-CIS-1.1.1.ps1 @@ -0,0 +1,3541 @@ +$parentPath = Split-Path -Parent -Path $PSScriptRoot +$scriptPath = $parentPath + "/Helpers/ShellScripts/SLE_15/" +$rcTrue = "True" +$rcCompliant = "Compliant" +$rcFalse = "False" +$rcNone = "None" +$rcNonCompliant = "Non-Compliant" +$rcNonCompliantManualReviewRequired = "Manual Review Required" +$rcCompliantIPv6isDisabled = "IPv6 is disabled" +$rcFirewallStatus1 = "Using firewalld with iptables" +$rcFirewallStatus2 = "Using nftables" +$rcFirewallStatus3 = "Using iptables" + +$retCompliant = @{ + Message = $rcCompliant + Status = $rcTrue +} +$retNonCompliant = @{ + Message = $rcNonCompliant + Status = $rcFalse +} +$retCompliantIPv6Disabled = @{ + Message = $rcCompliantIPv6isDisabled + Status = $rcTrue +} +$retNonCompliantManualReviewRequired = @{ + Message = $rcNonCompliantManualReviewRequired + Status = $rcNone +} +$retUsingFW1 = @{ + Message = $rcFirewallStatus1 + Status = $rcNone +} +$retUsingFW2 = @{ + Message = $rcFirewallStatus2 + Status = $rcNone +} +$retUsingFW3 = @{ + Message = $rcFirewallStatus3 + Status = $rcNone +} + + +$IPv6Status_script = @' +#!/bin/bash +[ -n "$passing" ] && passing="" +[ -z "$(grep "^\s*linux" /boot/grub2/grub.cfg | grep -v ipv6.disabled=1)" ] && passing="true" +grep -Eq "^\s*net\.ipv6\.conf\.all\.disable_ipv6\s*=\s*1\b(\s+#.*)?$" /etc/sysctl.conf /etc/sysctl.d/*.conf && grep -Eq "^\s*net\.ipv6\.conf\.default\.disable_ipv6\s*=\s*1\b(\s+#.*)?$" /etc/sysctl.conf /etc/sysctl.d/*.conf && sysctl net.ipv6.conf.all.disable_ipv6 | grep -Eq "^\s*net\.ipv6\.conf\.all\.disable_ipv6\s*=\s*1\b(\s+#.*)?$" && sysctl net.ipv6.conf.default.disable_ipv6 | grep -Eq "^\s*net\.ipv6\.conf\.default\.disable_ipv6\s*=\s*1\b(\s+#.*)?$" && passing="true" +if [ "$passing" = true ] ; then + echo "IPv6 is disabled on the system" +else + echo "IPv6 is enabled on the system" +fi +'@ +$IPv6Status = bash -c $IPv6Status_script +if ($IPv6Status -match "enabled") { + $IPv6Status = "enabled" +} else { + $IPv6Status = "disabled" +} + + +# Firewall evaluation +function GetFirewallStatus { + # 0 = init. value, undefined + # 1 = using firewalld with iptabes as backend + # 2 = using nftables + # 3 = using iptables + $FirewallStatus = 0 + + # Testing for firewalld with iptables as backend + $test1 = rpm -q firewalld iptables + $test2 = rpm -q nftables + $test3 = systemctl status nftables | grep "active (running)" + $test4 = systemctl is-enabled nftables + $test5 = systemctl is-enabled firewalld + $test6 = firewall-cmd --state + if($test1 -match "firewalld-" -and $test1 -match "iptables-" -and (!($test2 -match "nftables-") -or !($test3 -match "active (running)")) -and !($test4 -match "enabled") -and $test5 -match "enabled" -and $test6 -match "running") { + return 1 + } + + # Testing for nftables + $test1 = rpm -q nftables + $test2 = rpm -q firewalld + $test3 = systemctl status firewalld | grep "active (running)" + $test4 = systemctl is-enabled firewalld + $test5 = systemctl is-enabled nftables + if($test1 -match "nftables-" -and !($test2 -match "firewalld-" -or $test3 -match "active (running)") -and !($test4 -match "enabled") -and $test5 -match "enabled") { + return 2 + } + + # Testing for iptables + $test1 = rpm -q iptables + $test2 = rpm -q nftables + $test3 = rpm -q firewalld + $test4 = systemctl status firewalld | grep "active (running)" + $test5 = systemctl is-enabled firewalld + if($test1 -match "iptables-" -and $test2 -match "not installed" -and $test3 -match "not installed" -and !($test4 -match "running (active)") -and !($test5 -match "enabled")) { + return 3 + } + + return $FirewallStatus +} + +$FirewallStatus = GetFirewallStatus +### Chapter 1 - Initial Setup + +[AuditTest] @{ + Id = "1.1.1.1" + Task = "Ensure mounting of squashfs filesystems is disabled" + Test = { + $result1 = modprobe -n -v squashfs | grep -E '(suqashfs|install)' + $result2 = lsmod | grep squashfs + if ($result1 -match "install /bin/true" -and $result2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.1.2" + Task = "Ensure mounting of udf filesystems is disabled" + Test = { + $result1 = modprobe -n -v udf | grep -E '(udf|install)' + $result2 = lsmod | grep udf + if ($result1 -match "install /bin/true" -and $result2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.1.3" + Task = "Ensure mounting of FAT filesystems is disabled" + Test = { + $result1 = modprobe -n -v fat | grep -E '(fat|install)' + $result2 = lsmod | grep udf + $result3 = modprobe -n -v vfat | grep -E '(vfat|install)' + $result4 = lsmod | grep udf + $result5 = modprobe -n -v msdos | grep -E '(msdos|install)' + $result6 = lsmod | grep udf + if ($result1 -match "install /bin/true" -and $result2 -eq $null -and $result3 -match "install /bin/true" -and $result4 -eq $null -and $result5 -match "install /bin/true" -and $result6 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.2" + Task = "Ensure /tmp is configured" + Test = { + $result1 = mount | grep -E '\s/tmp\s' + if ($result1 -match "/tmp") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.3" + Task = "Ensure noexec option set on /tmp partition" + Test = { + $result1 = mount | grep -E '\s/tmp\s' | grep -v noexec + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.4" + Task = "Ensure nodev option set on /tmp partition" + Test = { + $result1 = mount | grep -E '\s/tmp\s' | grep -v nodev + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.5" + Task = "Ensure nosuid option set on /tmp partition" + Test = { + $result1 = mount | grep -E '\s/tmp\s' | grep -v nosuid + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.6" + Task = "Ensure /dev/shm is configured" + Test = { + $result1 = mount | grep -E '\s/dev/shm\s' + $result2 = grep -E '\s/dev/shm\s' /etc/fstab + if ($result1 -ne $null -and $result2 -ne $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.7" + Task = "Ensure noexec option set on /dev/shm partition" + Test = { + $result1 = mount | grep -E '\s/dev/shm\s' | grep -v noexec + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.8" + Task = "Ensure nodev option set on /dev/shm partition" + Test = { + $result1 = mount | grep -E '\s/dev/shm\s' | grep -v nodev + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.9" + Task = "Ensure nosuid option set on /dev/shm partition" + Test = { + $result1 = mount | grep -E '\s/dev/shm\s' | grep -v nosuid + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.10" + Task = "Ensure separate partition exists for /var" + Test = { + $result1 = mount | grep -E '\s/var\s' + if ($result1 -ne $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.11" + Task = "Ensure separate partition exists for /var/tmp" + Test = { + $result1 = mount | grep /var/tmp + if ($result1 -ne $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.12" + Task = "Ensure noexec option set on /var/tmp partition" + Test = { + $result1 = mount | grep -E '\s/var/tmp\s' | grep -v noexec + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.13" + Task = "Ensure nodev option set on /var/tmp partition" + Test = { + $result1 = mount | grep -E '\s/var/tmp\s' | grep -v nodev + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.14" + Task = "Ensure nosuid option set on /var/tmp partition" + Test = { + $result1 = mount | grep -E '\s/var/tmp\s' | grep -v nosuid + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.15" + Task = "Ensure separate partition exists for /var/log" + Test = { + $result1 = mount | grep -E '\s/var/log\s' + if ($result1 -ne $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.16" + Task = "Ensure separate partition exists for /var/log/audit" + Test = { + $result1 = mount | grep /var/log/audit + if ($result1 -ne $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.17" + Task = "Ensure separate partition exists for /home" + Test = { + $result1 = mount | grep /home + if ($result1 -ne $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.18" + Task = "Ensure nodev option set on /home partition" + Test = { + $result1 = mount | grep -E '\s/home\s' | grep -v nodev + if ($result1 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.19" + Task = "Ensure noexec option set on removable media partitions" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "1.1.20" + Task = "Ensure nodev option set on removable media partitions" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "1.1.21" + Task = "Ensure nosuid option set on removable media partitions" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "1.1.22" + Task = "Ensure sticky bit is set on all world-writable directories" + Test = { + $result_script = @' +#!/bin/bash +df --local -P 2>/dev/null | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type d \( -perm -0002 -a ! -perm -1000 \) 2>/dev/null +'@ + $result = bash -c $result_script + if ($result -ne $null) { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.23" + Task = "Disable Automounting" + Test = { + $result = systemctl is-enabled autofs + if ($result -match "enabled") { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "1.2.1" + Task = "Ensure GPG keys are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "1.2.2" + Task = "Ensure package manager repositories are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "1.2.3" + Task = "Ensure gpgcheck is globally activated" + Test = { + $result = grep ^\s*gpgcheck /etc/zypp/zypp.conf + if ($result -match "gpgcheck=1") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.3.1" + Task = "Ensure sudo is installed" + Test = { + $result = rpm -q sudo + if ($result -match "sudo-") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.3.2" + Task = "Ensure sudo commands use pty" + Test = { + $result = grep -Ei '^\s*Defaults\s+([^#]\S+,\s*)?use_pty\b' /etc/sudoers /etc/sudoers.d/* + if ($result -match "Defaults user_pty") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.3.3" + Task = "Ensure sudo log file exists" + Test = { + $result = grep -Ei '^\s*Defaults\s+([^#;]+,\s*)?logfile\s*=\s*(")?[^#;]+(")?' /etc/sudoers /etc/sudoers.d/* + if ($result -match "Defaults logfile=") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.4.1" + Task = "Ensure aide is installed" + Test = { + $result = rpm -q aide + if ($result -match "aide-") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.4.2" + Task = "Ensure filesystem integrity is regularly checked" + Test = { + $result1 = crontab -u root -l | grep aide + $result2 = grep -r aide /etc/cron.* /etc/crontab + if ($result1 -ne $null -or $result2 -ne $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.5.1" + Task = "Ensure bootloader password is set" + Test = { + $result1 = grep "^\s*set superusers" /boot/grub2/grub.cfg + $result2 = grep "^\s*password" /boot/grub2/grub.cfg + if ($result1 -match "set superusers=" -and $result2 -match "password_pbkdf2 ") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.5.2" + Task = "Ensure permissions on bootloader config are configured" + Test = { + $result = stat /boot/grub2/grub.cfg | grep "Uid: " + $result = $result | cut -d '(' -f 2 + $result = $result | cut -d '/' -f 1 + if($result -eq "0400" -or $result[1] -le 4){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.5.3" + Task = "Ensure authentication required for single user mode" + Test = { + $result1 = grep /systemd-sulogin-shell /usr/lib/systemdm/system/rescue.service + $result2 = grep /systemd-sulogin-shell /usr/lib/systemdm/system/rescue.service + if($result1 -ne $null -and $result2 -ne $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.6.1" + Task = "Ensure core dumps are restricted" + Test = { + $result1 = grep -E "^\s*\*\s+hard\s+core" /etc/security/limits.conf + $result2 = sysctl fs.suid_dumpable + $result3 = grep "fs\.suid_dumpable" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "hard core 0" -and $result2 -match "fs.suid_dumpable = 0" -and $result3 -match "fs.suid_dumpable = 0") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +# 1.6.2 implemented for journalctl only +[AuditTest] @{ + Id = "1.6.2" + Task = "Ensure XD/NX support is enabled" + Test = { + $result1 = journalctl | grep 'protection: active' + if($result1 -match "protection: active") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.6.3" + Task = "Ensure address space layout randomization (ASLR) is enabled" + Test = { + $result1 = sysctl kernel.randomize_va_space + $result2 = grep "kernel\.randomize_va_space" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "kernel.randomize_va_space = 2" -and $result2 -match "kernel.randomize_va_space = 2") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.6.4" + Task = "Ensure prelink is disabled" + Test = { + $result1 = rpm -q prelink + if($result1 -match "package prelink is not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.7.1.1" + Task = "Ensure AppArmor is installed" + Test = { + $result1 = rpm -q apparmor-docs apparmor-parser apparmor-profiles apparmor-utils libapparmor1 + if($result1 -ne $null -or $result2 -ne $null) { + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "1.7.1.2" + Task = "Ensure AppArmor is enabled in the bootloader configuration" + Test = { + $result1 = grep "^\s*linux" /boot/grub2/grub.cfg | grep -v "apparmor=1" + $result2 = grep "^\s*linux" /boot/grub2/grub.cfg | grep -v "security=apparmor" + if($result1 -eq $null -and $result2 -eq $null) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.7.1.3" + Task = "Ensure all AppArmor Profiles are in enforce or complain mode" + Test = { + $profileMode1 = apparmor_status | grep profiles | sed '1!d' | cut -d ' ' -f 1 + $profileMode2 = apparmor_status | grep profiles | sed '2!d' | cut -d ' ' -f 1 + $profileMode3 = apparmor_status | grep profiles | sed '3!d' | cut -d ' ' -f 1 + $result = expr $profileMode3 + $profileMode2 + $unconfinedProcesses = apparmor_status | grep processes | sed '4!d' | cut -d ' ' -f 1 + if ($result -eq $profileMode1 -and $unconfinedProcesses -eq 0) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.7.1.4" + Task = "Ensure all AppArmor Profiles are enforcing" + Test = { + $profileMode1 = apparmor_status | grep profiles | sed '1!d' | cut -d ' ' -f 1 + $profileMode2 = apparmor_status | grep profiles | sed '2!d' | cut -d ' ' -f 1 + + $unconfinedProcesses = apparmor_status | grep processes | sed '4!d' | cut -d ' ' -f 1 + + if($profileMode1 -eq $profileMode2 -and $unconfinedProcesses -eq 0){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.1.1" + Task = "Ensure message of the day is configured properly" + Test = { + $result = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/motd 2>/dev/null + if($result -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.1.2" + Task = "Ensure local login warning is configured peoperly" + Test = { + $result = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue + if($result -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.1.3" + Task = "Ensure remote login warning banner is configured properly" + Test = { + $script = $scriptPath + "CIS-SEL15-1.8.1.3.sh" + $result = bash $script + if($result -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.1.4" + Task = "Ensure permissions on /etc/motd are configured" + Test = { + $result = stat -L /etc/motd | grep "0644" + if($result -eq $null -or $result -match "0644"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.8.1.5" + Task = "Ensure permissions on /etc/issue are configured" + Test = { + $result = stat -L /etc/issue | grep "0644" + if($result -ne $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +if (Test-Path -Path '/etc/issue.net') { +[AuditTest] @{ + Id = "1.8.1.6" + Task = "Ensure permissions on /etc/issue.net are configured" + Test = { + $result = stat -L /etc/issue.net | grep "0644" + if($result -ne $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} +} + +[AuditTest] @{ + Id = "1.9" + Task = "Ensure updates, patches, and additional security software are installed" + Test = { + $output = zypper list-updates + $output = $? + if($output -match "True"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.10" + Task = "Ensure GDM is removed or login is configured" + Test = { + $result = rpm -q gdm + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +### Chapter 2 - Services + +[AuditTest] @{ + Id = "2.1.1" + Task = "Ensure xinetd is not installed" + Test = { + $result = rpm -q xinetd + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.1.1" + Task = "Ensure time synchronization is in use" + Test = { + $result = rpm -q chrony + if($result -match "chrony-"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.1.2" + Task = "Ensure systemd-timesyncd is configured" + Test = { + $result = systemctl is-enabled systemd-timesyncd.service + if($result -match "enabled"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.1.3" + Task = "Ensure chrony is configured" + Test = { + $result1 = grep -E "^(server|pool)" /etc/chrony.conf + $result2 = grep ^OPTIONS /etc/sysconfig/chronyd + if($result1 -match "server " -and $result2 -match "-u chrony") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.2" + Task = "Ensure X11 Server components are not installed" + Test = { + $result = rpm -qa xorg-x11-server* + if($result -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.4" + Task = "Ensure CUPS is not installed" + Test = { + $result = rpm -q cups + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.5" + Task = "Ensure DHCP Server is not installed" + Test = { + $result = rpm -q dhcp + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.6" + Task = "Ensure LDAP server is not installed" + Test = { + $result = rpm -q openldap2 + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.7" + Task = "Ensure nfs-utils is not installed or the nfs-server service is masked" + Test = { + $result1 = rpm -q nfs-utils + $result2 = rpm -q nfs-kernel-server + if($result1 -match "not installed" -and $result2 -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.8" + Task = "Ensure rpcbind is not installed or the rpcbind services are masked" + Test = { + $result = rpm -q rpcbind + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.9" + Task = "Ensure DNS Server is not installed" + Test = { + $result = rpm -q bind + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.10" + Task = "Ensure FTP Server is not installed" + Test = { + $result = rpm -q vsftpd + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.11" + Task = "Ensure HTTP Server is not installed" + Test = { + $result = rpm -q apache2 + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.12" + Task = "Ensure HTTP Server is not installed" + Test = { + $result = rpm -q dovecot + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.13" + Task = "Ensure Samba is not installed" + Test = { + $result = rpm -q samba + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.14" + Task = "Ensure HTTP Proxy Server is not installed" + Test = { + $result = rpm -q squid + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.15" + Task = "Ensure net-snmp is not installed" + Test = { + $result = rpm -q net-snmp + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.16" + Task = "Ensure mail transfer agent is configured for local-only mode" + Test = { + $result = ss -lntu | grep -E ':25\s' | grep -E -v '\s(127.0.0.1|\[?::1\]?):25\s' + if($result -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.17" + Task = "Ensure rsync is not installed or the rsyncd service is masked" + Test = { + $result = rpm -q rsync + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.18" + Task = "Ensure NIS server is not installed" + Test = { + $result = rpm -q ypserv + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.2.19" + Task = "Ensure telnet-server is not installed" + Test = { + $result = rpm -q telnet-server + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.3.1" + Task = "Ensure NIS Client is not installed" + Test = { + $result = rpm -q ypbind + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.3.2" + Task = "Ensure rsh client is not installed" + Test = { + $result = rpm -q rsh + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.3.3" + Task = "Ensure talk client is not installed" + Test = { + $result = rpm -q talk + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.3.4" + Task = "Ensure telnet client is not installed" + Test = { + $result = rpm -q telnet + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.3.5" + Task = "Ensure LDAP client is not installed" + Test = { + $result = rpm -q openldap2-clients + if($result -match "not installed"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "2.4" + Task = "Ensure nonessential services are removed or masked" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +## Chapter 3 - Network Configuration + +# sysctl wird ignoriert +[AuditTest] @{ + Id = "3.1.1" + Task = "Disable IPv6" + Test = { + if ($IPv6Status -match "disable") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.1.2" + Task = "Ensure wireless interfaces are disabled" + Test = { + $result = ip link show up + if($result -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.2.1" + Task = "Ensure IP forwarding is disabled" + Test = { + if ($IPv6Status -match "disable") { + $result1 = sysctl net.ipv4.ip_forward + $result2 = grep -E -s "^\s*net\.ipv4\.ip_forward\s*=\s*1" /etc/sysctl.conf /etc/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /run/sysctl.d/*.conf + if($result1 -match "net.ipv4.ip_forward = 0" -and $result2 -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } else { + $result1 = sysctl net.ipv4.ip_forward + $result2 = grep -E -s "^\s*net\.ipv4\.ip_forward\s*=\s*1" /etc/sysctl.conf /etc/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /run/sysctl.d/*.conf + $result3 = sysctl net.ipv6.conf.all.forwarding + $result4 = grep -E -s "^\s*net\.ipv6\.conf\.all\.forwarding\s*=\s*1" /etc/sysctl.conf /etc/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /run/sysctl.d/*.conf + if($result1 -match "net.ipv4.ip_forward = 0" -and $result2 -eq $null -and $result3 -match "net.ipv6.conf.all.forwarding = 0" -and $result4 -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } + + } +} + +[AuditTest] @{ + Id = "3.2.2" + Task = "Ensure packet redirect sending is disabled" + Test = { + $result1 = sysctl net.ipv4.conf.all.send_redirects + $result2 = sysctl net.ipv4.conf.default.send_redirects + $result3 = grep "net\.ipv4\.conf\.all\.send_redirects" /etc/sysctl.conf /etc/sysctl.d/* + $result4 = grep "net\.ipv4\.conf\.default\.send_redirects" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "net.ipv4.conf.all.send_redirects = 0" -and $result2 -match "net.ipv4.conf.default.send_redirects = 0" -and $result3 -match "net.ipv4.conf.all.send_redirects = 0" -and $result4 -match "net.ipv4.conf.default.send_redirects= 0"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.1" + Task = "Ensure source routed packets are not accepted" + Test = { + if ($IPv6Status -match "disable") { + $result1 = sysctl net.ipv4.conf.all.accept_source_route + $result2 = sysctl net.ipv4.conf.default.accept_source_route + $result3 = grep "net\.ipv4\.conf\.all\.accept_source_route" /etc/sysctl.conf /etc/sysctl.d/* + $result4 = grep "net\.ipv4\.conf\.default\.accept_source_route" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "net.ipv4.conf.all.accept_source_route = 0" -and $result2 -match "net.ipv4.conf.default.accept_source_route = 0" -and $result3 -match "net.ipv4.conf.all.accept_source_route= 0" -and $result4 -match "net.ipv4.conf.default.accept_source_route= 0"){ + return $retCompliant + } else { + return $retNonCompliant + } + } else { + $result1 = sysctl net.ipv4.conf.all.accept_source_route + $result2 = sysctl net.ipv4.conf.default.accept_source_route + $result3 = grep "net\.ipv4\.conf\.all\.accept_source_route" /etc/sysctl.conf /etc/sysctl.d/* + $result4 = grep "net\.ipv4\.conf\.default\.accept_source_route" /etc/sysctl.conf /etc/sysctl.d/* + $result5 = sysctl net.ipv6.conf.all.accept_source_route + $result6 = sysctl net.ipv6.conf.default.accept_source_route + $result7 = grep "net\.ipv6\.conf\.all\.accept_source_route" /etc/sysctl.conf /etc/sysctl.d/* + $result8 = grep "net\.ipv6\.conf\.default\.accept_source_route" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "net.ipv4.conf.all.accept_source_route = 0" -and $result2 -match "net.ipv4.conf.default.accept_source_route = 0" -and $result3 -match "net.ipv4.conf.all.accept_source_route= 0" -and $result4 -match "net.ipv4.conf.default.accept_source_route= 0" -and $result5 -match "net.ipv6.conf.all.accept_source_route = 0" -and $result6 -match "net.ipv6.conf.default.accept_source_route = 0" -and $result7 -match "net.ipv4.conf.all.accept_source_route= 0" -and $result8 -match "net.ipv6.conf.default.accept_source_route= 0"){ + return $retCompliant + } else { + return $retNonCompliant + } + } + } +} + +[AuditTest] @{ + Id = "3.3.2" + Task = "Ensure ICMP redirects are not accepted" + Test = { + $result1 = sysctl net.ipv4.conf.all.accept_redirects + $result2 = sysctl net.ipv4.conf.default.accept_redirects + $result3 = grep "net\.ipv4\.conf\.all\.accept_redirects" /etc/sysctl.conf /etc/sysctl.d/* + $result4 = grep "net\.ipv4\.conf\.default\.accept_redirects" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "net.ipv4.conf.all.accept_redirects = 0" -and $result2 -match "net.ipv4.conf.default.accept_redirects = 0" -and $result3 -match "net.ipv4.conf.all.accept_redirects= 0" -and $result4 -match "net.ipv4.conf.default.accept_redirects= 0"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.3" + Task = "Ensure secure ICMP redirects are not accepted" + Test = { + $result1 = sysctl net.ipv4.conf.all.secure_redirects + $result2 = sysctl net.ipv4.conf.default.accept_redirects + $result3 = grep "net\.ipv4\.conf\.all\.accept_redirects" /etc/sysctl.conf /etc/sysctl.d/* + $result4 = grep "net\.ipv4\.conf\.default\.accept_redirects" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "net.ipv4.conf.all.accept_redirects = 0" -and $result2 -match "net.ipv4.conf.default.accept_redirects = 0" -and $result3 -match "net.ipv4.conf.all.accept_redirects= 0" -and $result4 -match "net.ipv4.conf.default.accept_redirects= 0"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.4" + Task = "Ensure suspicious packets are logged" + Test = { + $result1 = sysctl net.ipv4.conf.all.log_martians + $result2 = sysctl net.ipv4.conf.default.log_martians + $result3 = grep "net\.ipv4\.conf\.all\.log_martians" /etc/sysctl.conf /etc/sysctl.d/* + $result4 = grep "net\.ipv4\.conf\.default\.log_martians" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "net.ipv4.conf.all.log_martians = 1" -and $result2 -match "net.ipv4.conf.default.log_martians = 1" -and $result3 -match "net.ipv4.conf.all.log_martians = 1" -and $result4 -match "net.ipv4.conf.default.log_martians = 1"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.5" + Task = "Ensure broadcast ICMP requests are ignored" + Test = { + $result1 = sysctl net.ipv4.icmp_echo_ignore_broadcasts + $result2 = grep "net\.ipv4\.icmp_echo_ignore_broadcasts" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "net.ipv4.icmp_echo_ignore_broadcasts = 1" -and $result2 -match "net.ipv4.icmp_echo_ignore_broadcasts = 1"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.6" + Task = "Ensure bogus ICMP responses are ignored" + Test = { + $result1 = sysctl net.ipv4.icmp_ignore_bogus_error_responses + $result2 = grep "net.ipv4.icmp_ignore_bogus_error_responses" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "net.ipv4.icmp_ignore_bogus_error_responses = 1" -and $result2 -match "net.ipv4.icmp_ignore_bogus_error_responses = 1"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.7" + Task = "Ensure Reverse Path Filtering is enabled" + Test = { + $result1 = sysctl net.ipv4.conf.all.rp_filter + $result2 = sysctl net.ipv4.conf.default.rp_filter + $result3 = grep "net\.ipv4\.conf\.all\.rp_filter" /etc/sysctl.conf /etc/sysctl.d/* + $result4 = grep "net\.ipv4\.conf\.default\.rp_filter" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "net.ipv4.conf.all.rp_filter = 1" -and $result2 -match "net.ipv4.conf.default.rp_filter = 1" -and $result3 -match "net.ipv4.conf.all.rp_filter = 1" -and $result4 -match "net.ipv4.conf.default.rp_filter = 1"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.8" + Task = "Ensure TCP SYN Cookies is enabled" + Test = { + $result1 = sysctl net.ipv4.tcp_syncookies + $result2 = grep "net\.ipv4\.tcp_syncookies" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "net.ipv4.tcp_syncookies = 1" -and $result2 -match "net.ipv4.tcp_syncookies = 1"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.3.9" + Task = "Ensure IPv6 router advertisements are not accepted" + Test = { + if ($IPv6Status -match "disabled") { + return $retCompliantIPv6Disabled + } + $result1 = sysctl net.ipv6.conf.all.accept_ra + $result2 = sysctl net.ipv6.conf.default.accept_ra + $result3 = grep "net\.ipv6\.conf\.all\.accept_ra" /etc/sysctl.conf /etc/sysctl.d/* + $result4 = grep "net\.ipv6\.conf\.default\.accept_ra" /etc/sysctl.conf /etc/sysctl.d/* + if($result1 -match "net.ipv6.conf.all.accept_ra = 0" -and $result2 -match "net.ipv6.conf.default.accept_ra = 0" -and $result3 -match "net.ipv6.conf.all.accept_ra = 0" -and $result4 -match "net.ipv6.conf.default.accept_ra = 0"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.4.1" + Task = "Ensure TCP SYN Cookies is enabled" + Test = { + $result1 = modprobe -n -v dccp + $result2 = lsmod | grep dccp + if($result1 -match "install /bin/true" -and $result2 -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.4.2" + Task = "Ensure SCTP is disabled" + Test = { + $result1 = modprobe -n -v sctp + $result2 = lsmod | grep sctp + if($result1 -match "install /bin/true" -and $result2 -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +### Chapter 3.5.1.X firewalld +if( ($FirewallStatus -eq 0) -or ($FirewallStatus -eq 1) ){ +[AuditTest] @{ + Id = "3.5.1.1" + Task = "Ensure FirewallD is installed" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $result = rpm -q firewalld iptables + if($result -match "firewalld-" -and $result -match "iptables-"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.1.2" + Task = "Ensure nftables is not installed or stopped and masked" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $result1 = rpm -q nftables + $result21 = systemctl status nftables | grep "active (running)" + $result22 = systemctl is-enabled nftables + if($result1 -match "not installed" -or (!($result21 -match "active (running)") -and !($result22 -match "enabled"))){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.1.3" + Task = "Ensure firewalld service is enabled and running" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $result1 = systemctl is-enabled firewalld + $result2 = firewall-cmd --state + if($result1 -match "enabled" -and $result2 -match "running"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.1.4" + Task = "Ensure default zone is set" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $result = firewall-cmd --get-default-zone + if($result -ne $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.1.5" + Task = "Ensure network interfaces are assigned to appropriate zone" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "3.5.1.6" + Task = "Ensure unnecessary services and ports are not accepted" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + return $retNonCompliantManualReviewRequired + } +} +} + +### Chapter 3.5.2.X nftables +if( ($FirewallStatus -eq 0) -or ($FirewallStatus -eq 2) ){ +[AuditTest] @{ + Id = "3.5.2.1" + Task = "Ensure nftables is installed" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $result = rpm -q nftables + if($result -match "nftables-"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.2.2" + Task = "Ensure firewalld is not installed or stopped and masked" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $result1 = rpm -q firewalld + $result21 = systemctl status firewalld | grep "Active: " | grep -v "active (running) " + $result22 = systemctl is-enabled firewalld + if($result1 -match "not installed" -or ($result21 -eq $null -and $result22 -match "masked")){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.2.3" + Task = "Ensure iptables are flushed" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "3.5.2.4" + Task = "Ensure a table exists" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $result = nft list tables + if($result -match "table inet filter") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.2.5" + Task = "Ensure base chain exist" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $result1 = nft list ruleset | grep 'hook input' + $result2 = nft list ruleset | grep 'hook forward' + $result3 = nft list ruleset | grep 'hook output' + if($result1 -match "type filter hook input priority 0;" -and $result2 -match "type filter hook forward priority 0;" -and $result3 -match "type filter hook output priority 0;") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.2.6" + Task = "Ensure loopback traffic is configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $result1 = nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept' + $result2 = nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr' + if($result1 -match "iif ""lo"" accept" -and $result2 -match "ip saddr 127.0.0.0/8 counter packets 0 bytes 0 drop") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.2.7" + Task = "Ensure outbound and established connections are configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "3.5.2.8" + Task = "Ensure default deny firewall policy" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $result1 = nft list ruleset | grep 'hook input' + $result2 = nft list ruleset | grep 'hook forward' + $result3 = nft list ruleset | grep 'hook output' + if($result1 -match "type filter hook input priority 0; policy drop;" -and $result2 -match "type filter hook forward priority 0; policy drop;" -and $result3 -match "type filter hook output priority 0; policy drop;") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.2.9" + Task = "Ensure nftables service is enabled" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $result = systemctl is-enabled nftables + if($result -match "enabled") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.2.10" + Task = "Ensure nftables rules are permanent" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $retNonCompliantManualReviewRequired + } +} +} + +### Chapter 3.5.3.X iptables +if( ($FirewallStatus -eq 0) -or ($FirewallStatus -eq 3) ){ +[AuditTest] @{ + Id = "3.5.3.1.1" + Task = "Ensure iptables package is installed" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + $result = rpm -q iptables + if($result -match "iptables-") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.3.1.2" + Task = "Ensure nftables is not installed" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + $result = rpm -q nftables + if($result -match "not installed") { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.3.1.3" + Task = "Ensure firewalld is not installed or stopped and masked" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + $result1 = rpm -q firewalld + $result21 = systemctl status firewalld | grep "Active: " | grep -v "active (running) " + $result22 = systemctl is-enabled firewalld + if($result1 -match "not installed" -or ($result21 -eq $null -and $result22 -match "masked")){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.3.2.1" + Task = "Ensure default deny firewall policy" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + $output = iptables -L + $test11 = $output -match "DROP" | grep "Chain INPUT (policy DROP)" + $result11 = $? + $test12 = $output -match "REJECT" | grep "Chain INPUT (policy REJECT)" + $result12 = $? + $test21 = $output -match "DROP" | grep "Chain FORWARD (policy DROP)" + $result21 = $? + $test22 = $output -match "REJECT" | grep "Chain FORWARD (policy REJECT)" + $result22 = $? + $test31 = $output -match "DROP" | grep "Chain OUTPUT (policy DROP)" + $result31 = $? + $test32 = $output -match "REJECT" | grep "Chain OUTPUT (policy REJECT)" + $result32 = $? + if(($result11 -match "True" -or $result12 -match "True") -and ($result21 -match "True" -or $result22 -match "True") -and ($result31 -match "True" -or $result32 -match "True")){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.3.2.2" + Task = "Ensure iptables loopback traffic is configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + $test1 = iptables -L INPUT -v -n | grep "Chain\s*INPUT\s*(policy\s*DROP" + $test2 = iptables -L OUTPUT -v -n | grep "Chain\s*OUTPUT\s*(policy\s*DROP" + if($test1 -ne $null -and $test2 -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "3.5.3.2.3" + Task = "Ensure outbound and established connections are configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "3.5.3.2.4" + Task = "Ensure firewall rules exist for all open ports" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "3.5.3.3.1" + Task = "Ensure IPv6 default deny firewall policy" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + if ($IPv6Status -match "disabled") { + return $retCompliantIPv6Disabled + } + $output = ip6tables -L + $test11 = $output -match "DROP" | grep "Chain INPUT (policy DROP)" + $result11 = $? + $test12 = $output -match "REJECT" | grep "Chain INPUT (policy REJECT)" + $result12 = $? + $test21 = $output -match "DROP" | grep "Chain FORWARD (policy DROP)" + $result21 = $? + $test22 = $output -match "REJECT" | grep "Chain FORWARD (policy REJECT)" + $result22 = $? + $test31 = $output -match "DROP" | grep "Chain OUTPUT (policy DROP)" + $result31 = $? + $test32 = $output -match "REJECT" | grep "Chain OUTPUT (policy REJECT)" + $result32 = $? + if(($result11 -match "True" -or $result12 -match "True") -and ($result21 -match "True" -or $result22 -match "True") -and ($result31 -match "True" -or $result32 -match "True")){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.3.3.2" + Task = "Ensure IPv6 loopback traffic is configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + if ($IPv6Status -match "disabled") { + return $retCompliantIPv6Disabled + } + $output1 = ip6tables -L INPUT -v -n + $test1 = $output1 | grep "ACCEPT\s*all\s*lo\s**\s*::/0\s*::/0" + $test2 = $output1 | grep "DROP\s*all\s**\s**\s*::1\s*::/0" + $output2 = ip6tables -L OUTPUT -v -n + $test3 = $output2 | grep "ACCEPT\s*all\s*lo\s**\s*::/0\s*::/0" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "3.5.3.3.3" + Task = "Ensure IPv6 outbound and established connections are configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + if ($IPv6Status -match "disabled") { + return $retCompliantIPv6Disabled + } + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "3.5.3.3.4" + Task = "Ensure IPv6 firewall rules exist for all open ports" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW2 + } + if ($IPv6Status -match "disabled") { + return $retCompliantIPv6Disabled + } + return $retNonCompliantManualReviewRequired + } +} +} + +## Chapter 4 Logging and Auditing + +[AuditTest] @{ + Id = "4.1.1.1" + Task = "Ensure auditd is installed" + Test = { + $test = rpm -q audit + if($test -match "audit-"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.1.2" + Task = "Ensure auditd service is enabled and running" + Test = { + $test1 = systemctl is-enabled auditd + $test2 = systemctl status auditd | grep 'Active: active (running) ' + if($test1 -match "enabled" -and $test2 -ne $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.1.3" + Task = "Ensure auditing for processes that start prior to auditd is enabled" + Test = { + $test = grep "^\s*linux" /boot/grub2/grub.cfg | grep -v "audit=1" + if($test -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.2.1" + Task = "Ensure audit log storage size is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "4.1.2.2" + Task = "Ensure audit logs are not automatically deleted" + Test = { + $test = grep max_log_file_action /etc/audit/auditd.conf + if($test -match "max_log_file_action = keep_logs"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.2.3" + Task = "Ensure system is disabled when audit logs are full" + Test = { + $test1 = grep space_left_action /etc/audit/auditd.conf + $test2 = grep action_mail_acct /etc/audit/auditd.conf + $test3 = grep admin_space_left_action /etc/audit/auditd.conf + if($test1 -match "space_left_action = email" -and $test2 -match "action_mail_acct = root" -and $test3 -match "admin_space_left_action = halt"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.2.4" + Task = "Ensure system is disabled when audit logs are full" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "4.1.3" + Task = "Ensure system is disabled when audit logs are full" + Test = { + $test1 = grep time-change /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep time-change + if($test1 -match "/etc/audit/rules.d/time_change.rules:-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change" -and + $test1 -match "/etc/audit/rules.d/time_change.rules:-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change" -and + $test1 -match "/etc/audit/rules.d/time_change.rules:-a always,exit -F arch=b64 -S clock_settime -k time-change" -and + $test1 -match "/etc/audit/rules.d/time_change.rules:-a always,exit -F arch=b32 -S clock_settime -k time-change" -and + $test1 -match "/etc/audit/rules.d/time_change.rules:-w /etc/localtime -p wa -k time-change" -and + $test2 -match "-a always,exit -F arch=b64 -S adjtimex,settimeofday -F key=time-change" -and + $test2 -match "-a always,exit -F arch=b32 -S stime,settimeofday,adjtimex -F key=time-change" -and + $test2 -match "-a always,exit -F arch=b64 -S clock_settime -F key=time-change" -and + $test2 -match "-a always,exit -F arch=b32 -S clock_settime -F key=time-change" -and + $test2 -match "-w /etc/localtime -p wa -k time-change"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.4" + Task = "Ensure events that modify user/group information are collected" + Test = { + $test1 = grep identity /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep identity + if($test1 -match "/etc/audit/rules.d/identity.rules:-w /etc/group -p wa -k identity" -and + $test1 -match "/etc/audit/rules.d/identity.rules:-w /etc/passwd -p wa -k identity" -and + $test1 -match "/etc/audit/rules.d/identity.rules:-w /etc/shadow -p wa -k identity" -and + $test1 -match "/etc/audit/rules.d/identity.rules:-w /etc/security/opasswd -p wa -k identity" -and + $test2 -match "-w /etc/group -p wa -k identity" -and + $test2 -match "-w /etc/passwd -p wa -k identity" -and + $test2 -match "-w /etc/shadow -p wa -k identity" -and + $test2 -match "-w /etc/security/opasswd -p wa -k identity"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.5" + Task = "Ensure events that modify the system's network environment are collected" + Test = { + $test1 = grep system-locale /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep system-locale + if($test1 -match "/etc/audit/rules.d/system-locale.rules:-a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale" -and + $test1 -match "/etc/audit/rules.d/system-locale.rules:-a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale" -and + $test1 -match "/etc/audit/rules.d/system-locale.rules:-w /etc/issue -p wa -k system-locale" -and + $test1 -match "/etc/audit/rules.d/system-locale.rules:-w /etc/issue.net -p wa -k system-locale" -and + $test1 -match "/etc/audit/rules.d/system-locale.rules:-w /etc/hosts -p wa -k system-locale" -and + $test1 -match "/etc/audit/rules.d/system-locale.rules:-w /etc/sysconfig/network -p wa -k system-locale" -and + $test2 -match "-a always,exit -F arch=b64 -S sethostname,setdomainname -F key=system-locale" -and + $test2 -match "-a always,exit -F arch=b32 -S sethostname,setdomainname -F key=system-locale" -and + $test2 -match "-w /etc/issue -p wa -k system-locale" -and + $test2 -match "-w /etc/issue.net -p wa -k system-locale" -and + $test2 -match "-w /etc/hosts -p wa -k system-locale" -and + $test2 -match "-w /etc/sysconfig/network -p wa -k system-locale"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.6" + Task = "Ensure events that modify the system's Mandatory Access Controls are collected" + Test = { + $test1 = grep MAC-policy /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep MAC-policy + if($test1 -match "/etc/audit/rules.d/MAC_policy.rules:-w /etc/selinux/ -p wa -k MAC-policy" -and $test1 -match "/etc/audit/rules.d/MAC_policy.rules:-w /usr/share/selinux/ -p wa -k MAC-policy" -and $test2 -match "-w /etc/selinux/ -p wa -k MAC-policy" -and $test2 -match "-w /usr/share/selinux/ -p wa -k MAC-policy"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.7" + Task = "Ensure login and logout events are collected" + Test = { + $test1 = grep logins /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep logins + if($test1 -match "/etc/audit/rules.d/logins.rules:-w /var/log/faillog -p wa -k logins" -and + $test1 -match "/etc/audit/rules.d/logins.rules:-w /var/log/lastlog -p wa -k logins" -and + $test1 -match "/etc/audit/rules.d/logins.rules:-w /var/log/tallylog -p wa -k logins" -and + $test2 -match "-w /var/log/faillog -p wa -k logins" -and + $test2 -match "-w /var/log/lastlog -p wa -k logins" -and + $test2 -match "-w /var/log/tallylog -p wa -k logins"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.8" + Task = "Ensure session initiation information is collected" + Test = { + $test1 = grep -E '(session|logins)' /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep -E '(session|logins)' + if($test1 -match "/etc/audit/rules.d/session.rules:-w /var/run/utmp -p wa -k session" -and + $test1 -match "/etc/audit/rules.d/session.rules:-w /var/log/wtmp -p wa -k logins" -and + $test1 -match "/etc/audit/rules.d/session.rules:-w /var/log/btmp -p wa -k logins" -and + $test2 -match "-w /var/run/utmp -p wa -k session" -and + $test2 -match "-w /var/log/wtmp -p wa -k logins" -and + $test2 -match "-w /var/log/btmp -p wa -k logins"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.9" + Task = "Ensure discretionary access control permission modification events are collected" + Test = { + $test1 = grep perm_mod /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep perm_mod + if($test1 -match "/etc/audit/rules.d/perm_mod.rules:-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod" -and + $test1 -match "/etc/audit/rules.d/perm_mod.rules:-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod" -and + $test1 -match "/etc/audit/rules.d/perm_mod.rules:-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod" -and + $test1 -match "/etc/audit/rules.d/perm_mod.rules:-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod" -and + $test1 -match "/etc/audit/rules.d/perm_mod.rules:-a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod" -and + $test1 -match "/etc/audit/rules.d/perm_mod.rules:-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod" -and + $test2 -match "-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and + $test2 -match "-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and + $test2 -match "-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and + $test2 -match "-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and + $test2 -match "-a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and + $test2 -match "-a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=-1 -F key=perm_mod"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.10" + Task = "Ensure discretionary access control permission modification events are collected" + Test = { + $test1 = grep access /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep access + if($test1 -match "/etc/audit/rules.d/access.rules:-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access" -and + $test1 -match "/etc/audit/rules.d/access.rules:-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access" -and + $test1 -match "/etc/audit/rules.d/access.rules:-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access" -and + $test1 -match "/etc/audit/rules.d/access.rules:-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access" -and + $test2 -match "/etc/audit/rules.d/access.rules:-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access" -and + $test2 -match "-a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat -F exit=-EACCES -F auid>=1000 -F auid!=-1 -F key=access" -and + $test2 -match "-a always,exit -F arch=b64 -S open,truncate,ftruncate,creat,openat -F exit=-EPERM -F auid>=1000 -F auid!=-1 -F key=access" -and + $test2 -match "-a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat -F exit=-EPERM -F auid>=1000 -F auid!=-1 -F key=access"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.11" + Task = "Ensure use of privileged commands is collected" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "4.1.12" + Task = "Ensure successful file system mounts are collected" + Test = { + $test1 = grep mounts /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep mounts + if($test1 -match "/etc/audit/rules.d/mounts.rules:-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts" -and + $test1 -match "/etc/audit/rules.d/mounts.rules:-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts" -and + $test2 -match "-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=-1 -F key=mounts" -and + $test2 -match "-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=-1 -F key=mounts"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.13" + Task = "Ensure file deletion events by users are collected" + Test = { + $test1 = grep delete /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep delete + if($test1 -match "/etc/audit/rules.d/deletion.rules:-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete" -and + $test1 -match "/etc/audit/rules.d/deletion.rules:-a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete" -and + $test2 -match "-a always,exit -F arch=b64 -S rename,unlink,unlinkat,renameat -F auid>=1000 -F auid!=-1 -F key=delete" -and + $test2 -match "-a always,exit -F arch=b32 -S unlink,rename,unlinkat,renameat -F auid>=1000 -F auid!=-1 -F key=delete"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.14" + Task = "Ensure changes to system administration scope (sudoers) is collected" + Test = { + $test1 = grep scope /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep scope + if($test1 -match "/etc/audit/rules.d/scope.rules:-w /etc/sudoers -p wa -k scope" -and + $test1 -match "/etc/audit/rules.d/scope.rules:-w /etc/sudoers.d/ -p wa -k scope" -and + $test2 -match "-w /etc/sudoers -p wa -k scope" -and + $test2 -match "-w /etc/sudoers.d -p wa -k scope"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.15" + Task = "Ensure system administrator actions (sudolog) are collected" + Test = { + $test1 = grep -E "^\s*-w\s+$(grep -r logfile /etc/sudoers* | sed -e 's/.*logfile=//;s/,? .*//')\s+-p\s+wa\s+-k\s+actions" /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep actions + $test3 = echo "-w $(grep -r logfile /etc/sudoers* | sed -e 's/.*logfile=//;s/,? .*//') -p wa -k actions" + if($test1 -match $test3 -and $test2 -match $test3){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.16" + Task = "Ensure kernel module loading and unloading is collected" + Test = { + $test1 = grep modules /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep modules + if($test1 -match "/etc/audit/rules.d/modules.rules:-w /sbin/insmod -p x -k modules" -and + $test1 -match "/etc/audit/rules.d/modules.rules:-w /sbin/rmmod -p x -k modules" -and + $test1 -match "/etc/audit/rules.d/modules.rules:-w /sbin/modprobe -p x -k modules" -and + $test1 -match "/etc/audit/rules.d/modules.rules:-a always,exit -F arch=b64 -S init_module -S delete_module -k modules" -and + $test2 -match "-w /sbin/insmod -p x -k modules" -and + $test2 -match "-w /sbin/rmmod -p x -k modules" -and + $test2 -match "-w /sbin/modprobe -p x -k modules" -and + $test2 -match "-a always,exit -F arch=b64 -S init_module,delete_module -F key=modules"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.1.17" + Task = "Ensure the audit configuration is immutable" + Test = { + $test = grep "^\s*[^#]" /etc/audit/rules.d/*.rules | tail -1 + if($test -match "-e 2"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.1.1" + Task = "Ensure rsyslog is installed" + Test = { + $test = rpm -q rsyslog + if($test -match "rsyslog-"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.1.2" + Task = "Ensure rsyslog Service is enabled and running" + Test = { + $test1 = systemctl is-enabled rsyslog + $test2 = systemctl status rsyslog | grep 'active (running) ' + if($test1 -match "enabled" -and $test2 -ne $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.1.3" + Task = "Ensure rsyslog default file permissions configured" + Test = { + $test = grep ^\$FileCreateMode /etc/rsyslog.conf /etc/rsyslog.d/*.conf + if($test -match "FileCreateMode"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.1.4" + Task = "Ensure logging is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "4.2.1.5" + Task = "Ensure rsyslog is configured to send logs to a remote log host" + Test = { + $test = grep "^*.*[^I][^I]*@" /etc/rsyslog.conf /etc/rsyslog.d/*.conf + if($test -ne $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.1.6" + Task = "Ensure remote rsyslog messages are only accepted on designated log hosts" + Test = { + $test1 = grep '$ModLoad imtcp' /etc/rsyslog.conf /etc/rsyslog.d/*.conf + $test2 = grep '$InputTCPServerRun' /etc/rsyslog.conf /etc/rsyslog.d/*.conf + if($test1 -match "ModLoad imtcp" -and $test2 -match "InputTCPServerRun 514"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.2.1" + Task = "Ensure journald is configured to send logs to rsyslog" + Test = { + $test = grep -E ^\s*ForwardToSyslog /etc/systemd/journald.conf + if($test -match "ForwardToSyslog=yes"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.2.2" + Task = "Ensure journald is configured to compress large log files" + Test = { + $test = grep -E ^\s*Compress /etc/systemd/journald.conf + if($test -match "Compress=yes"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.2.3" + Task = "Ensure journald is configured to write logfiles to persistent disk" + Test = { + $test = grep -E ^\s*Storage /etc/systemd/journald.conf + if($test -match "Storage=persistent"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.3" + Task = "Ensure permissions on all logfiles are configured" + Test = { + $test = find /var/log -type f -perm /g+wx,o+rwx -exec ls -l '{}' \; + if($test -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "4.2.4" + Task = "Ensure logrotate is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "5.1.1" + Task = "Ensure cron daemon is enabled and running" + Test = { + $test1 = systemctl is-enabled cron + $test2 = systemctl status cron | grep 'Active: active (running) ' + if($test1 -eq $null -and $test2 -match "active (running)"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.2" + Task = "Ensure permissions on /etc/crontab are configured" + Test = { + $test = stat /etc/crontab + if($test -match "0600/-rw-"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.3" + Task = "Ensure permissions on /etc/cron.hourly are configured" + Test = { + $test = stat /etc/cron.hourly/ + if($test -match "0700/drwx"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.4" + Task = "Ensure permissions on /etc/cron.daily are configured" + Test = { + $test = stat /etc/cron.daily + if($test -match "0700/drwx"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.5" + Task = "Ensure permissions on /etc/cron.weekly are configured" + Test = { + $test = stat /etc/cron.weekly + if($test -match "0700/drwx"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.6" + Task = "Ensure permissions on /etc/cron.monthly are configured" + Test = { + $test = stat /etc/cron.weekly + if($test -match "0700/drwx"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.7" + Task = "Ensure permissions on /etc/cron.d are configured" + Test = { + $test = stat /etc/cron.weekly + if($test -match "0700/drwx"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.8" + Task = "Ensure cron is restricted to authorized users" + Test = { + $test = stat /etc/cron.deny + if($test -match "cannot stat"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.1.9" + Task = "Ensure cron is restricted to authorized users" + Test = { + $test1 = stat /etc/at.deny + $test2 = stat /etc/at.allow + if($test1 -match "cannot stat" -and $test2 -match "0600/-rw-"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.1" + Task = "Ensure permissions on /etc/ssh/sshd_config are configured" + Test = { + $test1 = stat /etc/ssh/sshd_config + if($test1 -match "0600/-rw-"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +### TODO ... +[AuditTest] @{ + Id = "5.2.2" + Task = "Ensure permissions on SSH private host key files are configured" + Test = { + return $retCompliant + } +} + +### TODO... +[AuditTest] @{ + Id = "5.2.3" + Task = "Ensure permissions on SSH public host key files are configured" + Test = { + return $retCompliant + } +} + +[AuditTest] @{ + Id = "5.2.4" + Task = "Ensure SSH access is limited" + Test = { + $test = sshd -T | grep -E '^\s*(allow|deny)(users|groups)\s+\S+' + if($test -match "allowusers " -or $test -match "allowgroups " -or $test -match "denyusers " -or $test -match "denygroups "){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.5" + Task = "Ensure SSH LogLevel is appropriate" + Test = { + $test = sshd -T | grep loglevel + if($test -match "loglevel\s+VERBOSE" -or $test -match "loglevel\s+INFO"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.6" + Task = "Ensure SSH X11 forwarding is disabled" + Test = { + $test = sshd -T | grep -i x11forwarding + if($test -match "x11forwarding no"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +### TODO +[AuditTest] @{ + Id = "5.2.7" + Task = "Ensure SSH MaxAuthTries is set to 4 or less" + Test = { + $test = sshd -T | grep maxauthtries | grep maxauthtries | cut -d ' ' -f 2 + if($test -le 4){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.8" + Task = "Ensure SSH IgnoreRhosts is enabled" + Test = { + $test = sshd -T | grep ignorerhosts + if($test -match "ignorehosts yes"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.9" + Task = "Ensure SSH HostbasedAuthentication is disabled" + Test = { + $test = sshd -T | grep hostbasedauthentication + if($test -match "hostbasedauthentication no"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.10" + Task = "Ensure SSH root login is disabled" + Test = { + $test = sshd -T | grep permitrootlogin + if($test -match "permitrootlogin no"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.11" + Task = "Ensure SSH PermitEmptyPasswords is disabled" + Test = { + $test = sshd -T | grep permitemptypasswords + if($test -match "permitemptypasswords no"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.12" + Task = "Ensure SSH PermitUserEnvironment is disabled" + Test = { + $test = sshd -T | grep permituserenvironment + if($test -match "permituserenvironment no"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.13" + Task = "Ensure only strong Ciphers are used" + Test = { + $test = sshd -T | grep ciphers + if($test -match "3des-cbc" -or $test -match "aes128-cbc" -or $test -match "aes192-cbc" -or $test -match "aes256-cbc"){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.14" + Task = "Ensure only strong MAC algorithms are used" + Test = { + $test = sshd -T | grep -i "MACs" + if($test -match "hmac-md5" -or + $test -match "hmac-md5-96" -or + $test -match "hmac-ripemd160" -or + $test -match "hmac-sha1" -or + $test -match "hmac-sha1-96" -or + $test -match "umac-64@openssh.com" -or + $test -match "umac-128@openssh.com" -or + $test -match "hmac-md5-etm@openssh.com" -or + $test -match "hmac-md5-96-etm@openssh.com" -or + $test -match "hmac-ripemd160-etm@openssh.com" -or + $test -match "hmac-sha1-etm@openssh.com" -or + $test -match "hmac-sha1-96-etm@openssh.com" -or + $test -match "umac-64-etm@openssh.com" -or + $test -match "umac-128-etm@openssh.com"){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.15" + Task = "Ensure only strong Key Exchange algorithms are used" + Test = { + $test = sshd -T | grep kexalgorithms + if($test -match "diffie-hellman-group1-sha1" -or + $test -match "diffie-hellman-group14-sha1" -or + $test -match "diffie-hellman-group-exchange-sha1"){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.16" + Task = "Ensure SSH Idle Timeout Interval is configured" + Test = { + $test1 = sshd -T | grep clientaliveinterval | cut -d ' ' -f 2 + $test2 = sshd -T | grep clientaliveinterval | cut -d ' ' -f 2 + if($test1 -ge 1 -and $test1 -le 300 -and $test2 -ge 1 -and $test2 -le 3){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.17" + Task = "Ensure SSH LoginGraceTime is set to one minute or less" + Test = { + $test = sshd -T | grep logingracetime | cut -d ' ' -f 2 + if($test -ge 1 -and $test1 -le 60){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +if (Test-Path -Path '/etc/issue.net') { +[AuditTest] @{ + Id = "5.2.18" + Task = "Ensure SSH warning banner is configured" + Test = { + $test = sshd -T | grep banner + if($test -match "banner /etc/issue.net"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} +} + +[AuditTest] @{ + Id = "5.2.19" + Task = "Ensure SSH PAM is enabled" + Test = { + $test = sshd -T | grep -i usepam + if($test -match "usepam yes"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.20" + Task = "Ensure SSH AllowTcpForwarding is disabled" + Test = { + $test = sshd -T | grep -i allowtcpforwarding + if($test -match "allowtcpforwarding no"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.21" + Task = "Ensure SSH MaxStartups is configured" + Test = { + $test = sshd -T | grep -i maxstartups + if($test -match "maxstartups 10:30:60"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.2.22" + Task = "Ensure SSH MaxSessions is limited" + Test = { + $test = sshd -T | grep -i maxsessions | cut -d ' ' -f 2 + if($test -le 10){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +# unfertig; nochmal drüber gehen TODO +[AuditTest] @{ + Id = "5.3.1" + Task = "Ensure password creation requirements are configured" + Test = { + $test1 = grep -P '^\s*password\s+(requisite|required)\s+pam_cracklib.so\s+([^#]+\s+)*minlen=(1[4-9]|[1-9][0-9]+)\b' /etc/pam.d/common-password + $test2 = grep -P '^\s*password\s+(?:requisite|required)\s+pam_cracklib\.so\s+(?:[^#]+\s+)*(?:(?!\2|\3|\4))(dcredit=-[1-9]|ucredit=-[1-9]|ocredit=-[1-9]|lcredit=-[1-9])\s+(?:[^#]+\s+)*(?:(?!\1|\3|\4))(dcredit=-[1-9]|ucredit=-[1-9]|ocredit=-[1-9]|lcredit=-[1-9])\s+(?:[^#]+\s+)*(?:(?!\1|\2|\4))(dcredit=-[1-9]|ucredit=-[1-9]|ocredit=-[1-9]|lcredit=-[1-9])\s+(?:[^#]+\s+)*(?!\1|\2|\3)(dcredit=-[1-9]|ucredit=-[1-9]|ocredit=-[1-9]|lcredit=-[1-9])' /etc/pam.d/common-password + if($test2 -match "dcredit=-1 ucredit=-1 lcredit=-1 ocredit=-1" -and $test1 -match "minlen=14"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +# unfertig; nochmal drüber gehen TODO +[AuditTest] @{ + Id = "5.3.2" + Task = "Ensure lockout for failed password attempts is configured" + Test = { + $test = grep -E '^\s*auth\s+\S+\s+pam_(tally2|unix)\.so' /etc/pam.d/login + if($test -match "deny=5"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.3.3" + Task = "Ensure password reuse is limited" + Test = { + $test = grep -P '^\s*password\s+(requisite|required)\s+pam_pwhistory\.so\s+([^#]+\s+)*remember=([5-9]|[1-9][0-9]+)\b' /etc/pam.d/common-password | cut -d= -f2 + if($test -ge 5){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.1.1" + Task = "Ensure password hashing algorithm is SHA-512" + Test = { + $test = grep -Ei '^\s*^\s*ENCRYPT_METHOD\s+SHA512' /etc/login.defs + if($test -match "SHA512"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.1.2" + Task = "Ensure password expiration is 365 days or less" + Test = { + $test1 = grep ^\s*PASS_MAX_DAYS /etc/login.defs | cut -f2 + $test2_script = @' +#!/bin/bash +for line in $(grep -E ^[^:]+:[^\*] /etc/shadow | cut -d: -f5) +do + if [ $line -gt 365 ] + then + echo "FAIL" + fi +done +'@ + $test2 = bash -c $test2_script + if($test1 -gt 365 -or $test2 -match "FAIL"){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.1.3" + Task = "Ensure minimum days between password changes is configured" + Test = { + $test1 = grep ^\s*PASS_MIN_DAYS /etc/login.defs | cut -f2 + $test2_script = @' +#!/bin/bash +for line in $(grep -E ^[^:]+:[^\*] /etc/shadow | cut -d: -f4) +do + if [ $line -lt 1 ] + then + echo "FAIL" + fi +done +'@ + $test2 = bash -c $test2_script + if($test1 -lt 1 -or $test2 -match "FAIL"){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.1.4" + Task = "Ensure password expiration warning days is 7 or more" + Test = { + $test1 = grep ^\s*PASS_WARN_AGE /etc/login.defs | cut -f2 + $test2_script = @' +#!/bin/bash +for line in $(grep -E ^[^:]+:[^\*] /etc/shadow | cut -d: -f6) +do + if [ $line -lt 7 ] + then + echo "FAIL" + fi +done +'@ + $test2 = bash -c $test2_script + if($test1 -lt 7 -or $test2 -match "FAIL"){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.1.5" + Task = "Ensure inactive password lock is 30 days or less" + Test = { + $test1 = useradd -D | grep INACTIVE | cut -d= -f2 + $test2_script = @' +#!/bin/bash +for line in $(grep -E ^[^:]+:[^\*] /etc/shadow | cut -d: -f7) +do + if [ $line -ge 30 ] + then + echo "FAIL" + fi +done +'@ + $test2 = bash -c $test2_script + if($test1 -gt 30 -or $test1 -eq -1 -or $test2 -match "FAIL"){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.1.6" + Task = "Ensure all users last password change date is in the past" + Test = { + $test_script = @' +#!/bin/bash +for usr in $(cut -d: -f1 /etc/shadow); do + [[ $(chage --list $usr | grep '^Last password change' | cut -d: -f2) > $(date) ]] && echo "$usr :$(chage --list $usr | grep '^Last password change' | cut -d: -f2)"; done +'@ + $test = bash -c $test_script + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.2" + Task = "Ensure system accounts are secured" + Test = { + $script1 = $scriptPath + "CIS-SEL15-5.4.2_1.sh" + $test1 = bash $script1 + $script2 = $scriptPath + "CIS-SEL15-5.4.2_2.sh" + $test2 = bash $script2 + if($test1 -eq $null -and $test2 -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.3" + Task = "Ensure default group for the root account is GID 0" + Test = { + $test = grep "^root:" /etc/passwd | cut -f4 + if($test -eq 0){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.4" + Task = "Ensure default user shell timeout is configured" + Test = { + $script = $scriptPath + "CIS-SEL15-5.4.4.sh" + $test1 = bash $script + $test2 = grep -PR '^\s*([^$#;]+\s+)*TMOUT=(9[0-9][1-9]|0+|[1-9]\d{3,})\b\s*(\S+\s*)*(\s+#.*)?$' /etc/profile* /etc/bashrc.bashrc* + if($test1 -match "configured in file: /etc/profile.d/" -and $test2 -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.4.5" + Task = "Ensure default user umask is configured" + Test = { + $test1 = grep -RPi '(^|^[^#]*)\s*umask\s+([0-7][0-7][01][0-7]\b|[0-7][0-7][0-7][0-6]\b|[0-7][01][0-7]\b|[0-7][0-7][0-6]\b|(u=[rwx]{0,3},)?(g=[rwx]{0,3},)?o=[rwx]+\b|(u=[rwx]{1,3},)?g=[^rx]{1,3}(,o=[rwx]{0,3})?\b)' /etc/login.defs /etc/default/login /etc/profile* /etc/bash.bashrc* + $test2 = grep -REi '^\s*UMASK\s+\s*(0[0-7][2-7]7|[0-7][2-7]7|u=(r?|w?|x?)(r?|w?|x?)(r?|w?|x?),g=(r?x?|x?r?),o=)\b' /etc/login.defs /etc/default/login /etc/profile* /etc/bash.bashrc* + if(($test1 -eq $null -or $test1 -match "No such file or directory") -and $test2 -match "UMASK\s*027"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "5.5" + Task = "Ensure root login is restricted to system console" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +#TODO +[AuditTest] @{ + Id = "5.6" + Task = "Ensure access to the su command is restricted" + Test = { + $test1 = grep -RPi '(^|^[^#]*)\s*umask\s+([0-7][0-7][01][0-7]\b|[0-7][0-7][0-7][0-6]\b|[0-7][01][0-7]\b|[0-7][0-7][0-6]\b|(u=[rwx]{0,3},)?(g=[rwx]{0,3},)?o=[rwx]+\b|(u=[rwx]{1,3},)?g=[^rx]{1,3}(,o=[rwx]{0,3})?\b)' /etc/login.defs /etc/default/login /etc/profile* /etc/bash.bashrc* + $test2 = grep -REi '^\s*UMASK\s+\s*(0[0-7][2-7]7|[0-7][2-7]7|u=(r?|w?|x?)(r?|w?|x?)(r?|w?|x?),g=(r?x?|x?r?),o=)\b' /etc/login.defs /etc/default/login /etc/profile* /etc/bash.bashrc* + if(($test1 -eq $null -or $test1 -match "No such file or directory") -and $test2 -match "UMASK\s*027"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + + +### Chapter 6 - System Maintenance + +[AuditTest] @{ + Id = "6.1.1" + Task = "Audit system file permissions" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "6.1.2" + Task = "Ensure permissions on /etc/passwd are configured" + Test = { + $test1 = stat /etc/passwd + if($test1 -match "0644"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.3" + Task = "Ensure permissions on /etc/shadow are configured" + Test = { + $test1 = stat /etc/shadow + if($test1 -match "0640"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.4" + Task = "Ensure permissions on /etc/group are configured" + Test = { + $test1 = stat /etc/group + if($test1 -match "0644"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.5" + Task = "Ensure permissions on /etc/passwd- are configured" + Test = { + $test1 = stat /etc/passwd- + if($test1 -match "0644"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.6" + Task = "Ensure permissions on /etc/shadow- are configured" + Test = { + $test1 = stat /etc/shadow- + if($test1 -match "0640"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.7" + Task = "Ensure permissions on /etc/group- are configured" + Test = { + $test1 = stat /etc/group- + if($test1 -match "0644"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.8" + Task = "Ensure no world writable files exist" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -0002 + if($test1 -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.9" + Task = "Ensure no unowned files or directories exist" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -0002 + if($test1 -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.10" + Task = "Ensure no ungrouped files or directories exist" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nogroup + if($test1 -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.1.11" + Task = "Audit SUID executables" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "6.1.12" + Task = "Audit SGID executables" + Test = { + return $retNonCompliantManualReviewRequired + } +} + +[AuditTest] @{ + Id = "6.2.1" + Task = "Ensure accounts in /etc/passwd use shadowed passwords" + Test = { + $script1 = $scriptPath + "CIS-SEL15-6.2.1.sh" + $test1 = bash $script1 + if($test1 -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.2" + Task = "Ensure /etc/shadow password fields are not empty" + Test = { + $script1 = $scriptPath + "CIS-SEL15-6.2.2.sh" + $test1 = bash $script1 + if($test1 -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.3" + Task = "Ensure root is the only UID 0 account" + Test = { + $test1_script = @' +#!/bin/bash +awk -F: '($3 == 0) { print $1 }' /etc/passwd +'@ + $test1 = bash -c $test1_script + if($test1 -match "root"){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.4" + Task = "Ensure root PATH Integrity" + Test = { + $test_script = @' +#!/bin/bash +if echo "$PATH" | grep -q "::" ; then + echo "Empty Directory in PATH (::)" +fi +if echo "$PATH" | grep -q ":$" ; then + echo "Trailing : in PATH" +fi +for x in $(echo "$PATH" | tr ":" " ") ; do + if [ -d "$x" ] ; then + ls -ldH "$x" | awk ' + $9 == "." {print "PATH contains current working directory (.)"} + $3 != "root" {print $9, "is not owned by root"} + substr($1,6,1) != "-" {print $9, "is group writable"} + substr($1,9,1) != "-" {print $9, "is world writable"}' + else + echo "$x is not a directory" + fi +done +'@ + $test = bash -c $test_script + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.5" + Task = "Ensure all users' home directories exist" + Test = { + $script1 = $scriptPath + "CIS-SEL15-6.2.5.sh" + $test = bash $script1 + if($test -match "does not exist"){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.6" + Task = "Ensure users' home directories permissions are 750 or more restrictive" + Test = { + $script1 = $scriptPath + "CIS-SEL15-6.2.6.sh" + $test = bash $script1 + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.7" + Task = "Ensure users own their home directories" + Test = { + $script1 = $scriptPath + "CIS-SEL15-6.2.7.sh" + $test = bash $script1 + if($test -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.8" + Task = "Ensure users' dot files are not group or world writable" + Test = { + $script1 = $scriptPath + "CIS-SEL15-6.2.8.sh" + $test = bash $script1 + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.9" + Task = "Ensure no users have .forward files" + Test = { + $script1 = $scriptPath + "CIS-SEL15-6.2.9.sh" + $test = bash $script1 + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.10" + Task = "Ensure no users have .netrc files" + Test = { + $script1 = $scriptPath + "CIS-SEL15-6.2.10.sh" + $test = bash $script1 + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.11" + Task = "Ensure users' .netrc Files are not group or world accessible" + Test = { + $script1 = $scriptPath + "CIS-SEL15-6.2.11.sh" + $test = bash $script1 + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.12" + Task = "Ensure no users have .rhosts files" + Test = { + $script1 = $scriptPath + "CIS-SEL15-6.2.12.sh" + $test = bash $script1 + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.13" + Task = "Ensure all groups in /etc/passwd exist in /etc/group" + Test = { + $test_script = @' +#!/bin/bash +for i in $(cut -s -d: -f4 /etc/passwd | sort -u ); do + grep -q -P "^.*?:[^:]*:$i:" /etc/group + if [ $? -ne 0 ]; then + echo "Group $i is referenced by /etc/passwd but does not exist in /etc/group" + fi +done +'@ + $test = bash -c $test_script + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.14" + Task = "Ensure no duplicate UIDs exist" + Test = { + $test_script = @' +#!/bin/bash +cut -f3 -d":" /etc/passwd | sort -n | uniq -c | while read x ; do + [ -z "$x" ] && break + set - $x + if (( $1 > 1 )); then + users=$(awk -F: '($3 == n) { print $1 }' n=$2 /etc/passwd | xargs) + echo "Duplicate UID ($2): $users" + fi +done +'@ + $test = bash -c $test_script + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.15" + Task = "Ensure no duplicate GIDs exist" + Test = { + $test_script = @' +#!/bin/bash +cut -d: -f3 /etc/group | sort | uniq -d | while read x ; do + echo "Duplicate GID ($x) in /etc/group" +done +'@ + $test = bash -c $test_script + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.16" + Task = "Ensure no duplicate user names exist" + Test = { + $test_script = @' +#!/bin/bash +cut -d: -f1 /etc/passwd | sort | uniq -d | while read x ; do + echo "Duplicate login name ${x} in /etc/passwd" +done +'@ + $test = bash -c $test_script + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.17" + Task = "Ensure no duplicate group names exist" + Test = { + $test_script = @' +#!/bin/bash +cut -d: -f1 /etc/group | sort | uniq -d | while read x ; do + echo "Duplicate group name ${x} in /etc/group" +done +'@ + $test = bash -c $test_script + if($test -ne $null){ + return $retNonCompliant + } else { + return $retCompliant + } + } +} + +[AuditTest] @{ + Id = "6.2.18" + Task = "Ensure shadow group is empty" + Test = { + $script1 = $scriptPath + "CIS-SEL15-6.2.18_1.sh" + $test1 = bash $script1 + $script2 = $scriptPath + "CIS-SEL15-6.2.18_2.sh" + $test2 = bash $script2 + if($test1 -eq $null -and $test2 -eq $null){ + return $retCompliant + } else { + return $retNonCompliant + } + } +} \ No newline at end of file diff --git a/ATAPAuditor/AuditGroups/Ubuntu Linux 20.04-CIS-1.1.0.ps1 b/ATAPAuditor/AuditGroups/Ubuntu Linux 20.04-CIS-1.1.0.ps1 new file mode 100644 index 0000000..a227dfc --- /dev/null +++ b/ATAPAuditor/AuditGroups/Ubuntu Linux 20.04-CIS-1.1.0.ps1 @@ -0,0 +1,5012 @@ +function Get-IPv6Disabled{ + $test1 = sysctl net.ipv6.conf.all.disable_ipv6 + $test2 = sysctl net.ipv6.conf.default.disable_ipv6 + $grep = grep -E '^\s*net\.ipv6\.conf\.(all|default)\.disable_ipv6\s*=\s*1\b(\s+#.*)?$'/etc/sysctl.conf /etc/sysctl.d/*.conf | cut -d: -f2 + if($test1 -match "net.ipv6.conf.all.disable_ipv6 = 1" -and $test2 -match "net.ipv6.conf.default.disable_ipv6 = 1" -and $grep -match "net.ipv6.conf.all.disable_ipv6 = 1" -and $grep -match "net.ipv6.conf.default.disable_ipv6 = 1"){ + return $true + } + return $false +} +$isIPv6Disabled = Get-IPv6Disabled + +[AuditTest] @{ + Id = "1.1.1.1" + Task = "Ensure mounting of cramfs filesystems is disabled" + Test = { + $result1 = modprobe -n -v cramfs | grep -E '(cramfs|install)' + $result2 = lsmod | grep cramfs + if($result1 -match "install /bin/true" -and $result2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.1.2" + Task = "Ensure mounting of freevxfs filesystems is disabled" + Test = { + $result1 = modprobe -n -v freevxfs | grep -E '(freevxfs|install)' + $result2 = lsmod | grep freevxfs + + if($result1 -match "install /bin/true" -and $result2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.1.3" + Task = "Ensure mounting of jffs2 filesystetms is disabled" + Test = { + $result1 = modprobe -n -v jffs2 | grep -E '(jffs2|install)' + $result2 = lsmod | grep jffs2 + + if($result1 -match "install /bin/true" -and $result2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.1.4" + Task = "Ensure mounting of hfs filesystetms is disabled" + Test = { + $result1 = modprobe -n -v hfs | grep -E '(hfs|install)' + $result2 = lsmod | grep hfs + + if($result1 -match "install /bin/true" -and $result2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.1.5" + Task = "Ensure mounting of hfsplus filesystetms is disabled" + Test = { + $result1 = modprobe -n -v hfsplus | grep -E '(hfsplus|install)' + $result2 = lsmod | grep hfsplus + + if($result1 -match "install /bin/true" -and $result2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.1.6" + Task = "Ensure mounting of squashfs filesystems is disabled" + Test = { + $result1 = modprobe -n -v squashfs | grep -E '(squashfs|install)' + $result2 = lsmod | grep squashfs + + if($result1 -match "install /bin/true" -and $result2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.1.7" + Task = "Ensure mounting of udf filesystetms is disabled" + Test = { + $result1 = modprobe -n -v udf | grep -E '(udf|install)' + $result2 = lsmod | grep udf + + if($result1 -match "install /bin/true" -and $result2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.2" + Task = "Ensure /tmp is configured" + Test = { + $result = findmnt -n /tmp + if($result -match "/tmp"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.3" + Task = "Ensure nodev option set on /tmp partition" + Test = { + $result = findmnt -n /tmp + if($result -match "nodev"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.4" + Task = "Ensure nosuid option set on /tmp partition" + Test = { + $result = findmnt -n /tmp + if($result -match "nosuid"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.5" + Task = "Ensure noexec option set on /tmp partition" + Test = { + $result = findmnt -n /tmp + if($result -match "noexec"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.6" + Task = "Ensure /dev/shm is configured" + Test = { + $result = findmnt -n /dev/shm + if($result -match "/dev/shm"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.7" + Task = "Ensure nodev option set on /dev/shm partition" + Test = { + $result = findmnt -n /dev/shm + if($result -match "nodev"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.8" + Task = "Ensure nosuid option set on /dev/shm partition" + Test = { + $result = findmnt -n /dev/shm + if($result -match "nosuid"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.9" + Task = "Ensure nosuid option set on /dev/shm partition" + Test = { + $result = findmnt -n /dev/shm | grep -v noexec + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.10" + Task = "Ensure separate partition exists for /var" + Test = { + $result = findmnt /var + if($result -match "/var"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.11" + Task = "Ensure separate partition exists for /var/tmp" + Test = { + $result = findmnt /var/tmp + if($result -match "/var/tmp"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.12" + Task = "Ensure /var/tmp partition includes the nodev option" + Test = { + $result = findmnt /var/tmp + if($result -match "nodev"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.13" + Task = "Ensure /var/tmp partition includes the nosuid option" + Test = { + $result = findmnt /var/tmp + if($result -match "nosuid"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.14" + Task = "Ensure /var/tmp partition includes the noexec option" + Test = { + $result = findmnt /var/tmp + if($result -match "noexec"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.15" + Task = "Ensure separate partition exists for /var/log" + Test = { + $result = findmnt /var/log + if($result -match "/var/log"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.16" + Task = "Ensure separate partition exists for /var/log/audit" + Test = { + $result = findmnt /var/log/audit + if($result -match "/var/log/audit"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.17" + Task = "Ensure separate partition exists for /home" + Test = { + $result = findmnt /home + if($result -match "/home"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.18" + Task = "Ensure /home partition includes the nodev option" + Test = { + $result = findmnt /home + if($result -match "nodev"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.19" + Task = "Ensure nodev option set on removable media partitions" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-1.1.19-1.1.21.sh" + $result=bash $path + foreach($line in $result){ + if(!($line -match "nodev")){ + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.20" + Task = "Ensure nosuid option set on removable media partitions" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-1.1.19-1.1.21.sh" + $result=bash $path + foreach($line in $result){ + if(!($line -match "nosuid")){ + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.21" + Task = "Ensure noexec option set on removable media partitions" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-1.1.19-1.1.21.sh" + $result=bash $path + foreach($line in $result){ + if(!($line -match "noexec")){ + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.1.22" + Task = "Ensure sticky bit is set on all world-writable directories" + Test = { + try{ + $result = bash -c "df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type d \( -perm -0002 -a ! -perm -1000 \) 2> /dev/null" + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "1.1.23" + Task = "Disable Automounting" + Test = { + $result = dpkg -l | grep -o autofs + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + else{ + $result = systemctl is-enabled autofs + if($result -match "No such file or directory"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.1.24" + Task = "Disable USB Storage" + Test = { + $result1 = modprobe -n -v usb-storage + $result2 = lsmod | grep usb-storage + if($result1 -match "install /bin/true" -and $result2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.2.1" + Task = "Ensure package manager repositories are configured" + Test = { + $result = apt-cache policy + if($result -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.2.2" + Task = "Ensure GPG keys are configured" + Test = { + $result = apt-key list + if($result -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.3.1" + Task = "Ensure AIDE is installed" + Test = { + $result1 = dpkg -l aide | grep '^ii' + $result2 = dpkg -l aide-common | grep '^ii' + if($result1 -eq $null -or $result2 -eq $null){ + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.3.2" + Task = "Ensure filesystem integrity is regularly checked" + Test = { + $result = grep -Ers '^([^#]+\s+)?(\/usr\/s?bin\/|^\s*)aide(\.wrapper)?\s(--check|\$AIDEARGS)\b' /etc/cron.* /etc/crontab /var/spool/cron/ + if($result -eq $null){ + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "1.4.1" + Task = "Ensure permissions on bootloader config are not overridden" + Test = { + $output = grep -E '^\s*chmod\s+[0-7][0-7][0-7]\s+\$\{grub_cfg\}\.new' -A 1 -B1 /usr/sbin/grub-mkconfig + if($output -match 'hmod 400 ${grub_cfg}.new || true'){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.4.2" + Task = "Ensure bootloader password is set" + Test = { + $result1 = grep "^set superusers" /boot/grub/grub.cfg + $result2 = grep "^password" /boot/grub/grub.cfg + if($result1 -match "set superusers=" -and $result2 -match "password_pbkdf2"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.4.3" + Task = "Ensure permissions on bootloader config are configured" + Test = { + $result = stat /boot/grub/grub.cfg | grep "Uid: ( 0/ root) Gid: ( 0/ root)" + $result = $result | cut -d '(' -f 2 + $result = $result | cut -d '/' -f 1 + + if($result -eq "0400" -or $result[1] -le 4){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.4.4" + Task = "Ensure authentication required for single user mode" + Test = { + $result = grep -Eq '^root:\$[0-9]' /etc/shadow || echo "root is locked" + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.5.1" + Task = "Ensure XD/NX support is enabled" + Test = { + $result = bash -c '[[ -n $(grep noexec[0-9]*=off /proc/cmdline) || -z $(grep -E -i " (pae|nx)" /proc/cpuinfo) || -n $(grep "\\sNX\\s.*\\sprotection:\\s" /var/log/dmesg | grep -v active) ]] && echo "NX Protection is not active"' + + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.5.2" + Task = "Ensure address space layout randomization (ASLR) is enabled" + Test = { + $result1 = sysctl kernel.randomize_va_space + $result2 = grep -Es "^\s*kernel\.randomize_va_space\s*=\s*([0-1]|[3-9]|[1-9][0-9]+)" /etc/sysctl.conf /etc/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /run/sysctl.d/*.conf + if($result1 -match "kernel.randomize_va_space = 2" -and $result2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.5.3" + Task = "Ensure prelink is not installed" + Test = { + $result = dpkg -l | grep -o prelink + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.5.4" + Task = "Ensure core dumps are restricted" + Test = { + try{ + $result1 = grep -Es '^(\*|\s).*hard.*core.*(\s+#.*)?$' /etc/security/limits.conf /etc/security/limits.d/* + $result2 = sysctl fs.suid_dumpable + $result3 = grep "fs.suid_dumpable" /etc/sysctl.conf /etc/sysctl.d/* + try{ + $result4 = systemctl is-enabled coredump.service + $message = "Compliant" + if($result4 -match "enabled" -or $result4 -match "masked" -or $result4 -match "disabled"){ + $message = "systemd-coredump is installed" + } + } + catch{ + $message = "systemd-coredump not installed" + } + if($result1 -match ".*\s*hard\s*core\s*0{1}?\s*" -and $result2 -match "fs.suid_dumpable = 0" -and $result3 -match "fs.suid_dumpable = 0"){ + return @{ + Message = $message + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "1.6.1.1" + Task = "Ensure AppArmor is installed" + Test = { + $result = dpkg -s apparmor | grep -E '(Status:|not installed)' + + if($result -match "Status: install ok installed"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.6.1.2" + Task = "Ensure AppArmor is enabled in the bootloader configuration" + Test = { + $result1 = grep "^\s*linux" /boot/grub/grub.cfg | grep -v "apparmor=1" + $result2 = grep "^\s*linux" /boot/grub/grub.cfg | grep -v "security=apparmor" + if($result1 -eq $null -and $result2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.6.1.3" + Task = "Ensure all AppArmor Profiles are in enforce or complain mode" + Test = { + $profileMode1 = apparmor_status | grep profiles | sed '1!d' | cut -d ' ' -f 1 + $profileMode2 = apparmor_status | grep profiles | sed '2!d' | cut -d ' ' -f 1 + $profileMode3 = apparmor_status | grep profiles | sed '3!d' | cut -d ' ' -f 1 + $result = expr $profileMode3 + $profileMode2 + + $unconfinedProcesses = apparmor_status | grep processes | sed '4!d' | cut -d ' ' -f 1 + + if($result -eq $profileMode1 -and $unconfinedProcesses -eq 0){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.6.1.4" + Task = "Ensure all AppArmor Profiles are enforcing" + Test = { + $profileMode1 = apparmor_status | grep profiles | sed '1!d' | cut -d ' ' -f 1 + $profileMode2 = apparmor_status | grep profiles | sed '2!d' | cut -d ' ' -f 1 + + $unconfinedProcesses = apparmor_status | grep processes | sed '4!d' | cut -d ' ' -f 1 + + if($profileMode1 -eq $profileMode2 -and $unconfinedProcesses -eq 0){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.7.1" + Task = "Ensure message of the day is configured properly" + Test = { + $output = grep -Eis "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/motd + + if($output -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.7.2" + Task = "Ensure local login warning banner is configured properly" + Test = { + $output1 = cat /etc/issue + $output2 = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue + + if($output1 -ne $null -and $output2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.7.3" + Task = "Ensure remote login warning banner is configured properly" + Test = { + $output1 = cat /etc/issue.net + $output2 = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue.net + + if($output1 -ne $null -and $output2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.7.4" + Task = "Ensure permissions on /etc/motd are configured" + Test = { + $output = stat -L /etc/motd | grep "Access:\s*(0644/-rw-r--r--)\s*Uid:\s*(\s*0/\s*root)\s*Gid:\s*(\s*0/\s*root)" + + if($output -eq $null -or $output -match "Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.7.5" + Task = "Ensure permissions on /etc/issue are configured" + Test = { + $output = stat -L /etc/issue | grep "Access:\s*(0644/-rw-r--r--)\s*Uid:\s*(\s*0/\s*root)\s*Gid:\s*(\s*0/\s*root)" + + if($output -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.7.6" + Task = "Ensure permissions on /etc/issue.net are configured" + Test = { + $output = stat -L /etc/issue.net | grep "Access:\s*(0644/-rw-r--r--)\s*Uid:\s*(\s*0/\s*root)\s*Gid:\s*(\s*0/\s*root)" + + if($output -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.1" + Task = "Ensure GNOME Display Manager is removed" + Test = { + $test1 = dpkg -l | grep -o gdm3 + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.2" + Task = "Ensure GNOME Display Manager is removed" + Test = { + if(Test-Path "/etc/gdm3/greeter.dconf-defaults"){ + $content = cat /etc/gdm3/greeter.dconf-defaults + $line1 = $content | grep "banner-message-enable=true" + $line2 = $content | grep "banner-message-text=" + if($line1 -ne $null -and $line1[0] -ne '#' -and $line2 -ne $null -and $line2[0] -ne '#'){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.3" + Task = "Ensure disable-user-list is enabled" + Test = { + if(Test-Path "/etc/gdm3/greeter.dconf-defaults"){ + $content = cat /etc/gdm3/greeter.dconf-defaults + $line = $content | grep "disable-user-list=true" + if($line -ne $null -and $line[0] -ne '#'){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.8.4" + Task = "Ensure XDCMP is not enabled" + Test = { + $output = grep -Eis '^\s*Enable\s*=\s*true' /etc/gdm3/custom.conf + if($output -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "1.9" + Task = "Ensure updates, patches, and additional security software are installed" + Test = { + $output = apt -s upgrade + $output = $? + if($output -match "True"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} + +[AuditTest] @{ + Id = "2.1.1.1" + Task = "Ensure time synchronization is in use" + Test = { + $test1 = systemctl is-enabled systemd-timesyncd + $test2 = dpkg -s ntp + $test3 = dpkg -s chrony + if($test1 -match "enabled" -or $test2 -match "Status: install ok installed" -or $test3 -match "Status: install ok installed"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +$ntp = dpkg -s ntp +$ntp = $? +$chrony = dpkg -s chrony +$chrony = $? +$timesyncd = systemctl is-enabled systemd-timesyncd + +if($ntp -match "False" -and $chrony -match "False"){ + [AuditTest] @{ + Id = "2.1.1.2" + Task = "Ensure systemd-timesyncd is configured" + Test = { + $test1 = systemctl is-enabled systemd-timesyncd.service + $time = timedatectl status + if($test1 -match "enabled" -and $time -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + } +} +elseif($ntp -match "False" -and $timesyncd -notmatch "enabled"){ + [AuditTest] @{ + Id = "2.1.1.3" + Task = "Ensure chrony is configured" + Test = { + $test1 = dpkg -s ntp | grep -E '(Status:|not installed)' + $test2 = systemctl is-enabled systemd-timesyncd + $test3 = grep -E "^(server|pool)" /etc/chrony/chrony.conf + $test4 = ps -ef | grep chronyd | grep "_chrony" + if($test1 -match "package 'ntp' is not installed" -and $test2 -match "masked" -and $test3 -ne $null -and $test4 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + } +} +elseif($chrony -match "False" -and $timesyncd -notmatch "enabled"){ + [AuditTest] @{ + Id = "2.1.1.4" + Task = "Ensure ntp is configured" + Test = { + $test1 = grep "^restrict" /etc/ntp.conf + $test2 = grep -E "^(server|pool)" /etc/ntp.conf + $test3 = grep "RUNASUSER=ntp" /etc/init.d/ntp + if($test1 -match "restrict -4 default kod notrap nomodify nopeer noquery limited" -and $test1 -match "restrict -6 default kod notrap nomodify nopeer noquery limited" -and $test2 -ne $null -and $test3 -match "RUNASUSER=ntp"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "2.1.2" + Task = "Ensure X Window System is not installed" + Test = { + $test1 = dpkg -l | grep -o xserver-xorg* + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.3" + Task = "Ensure Avahi Server is not installed" + Test = { + $status = dpkg -l | grep -o avahi-daemon + if($status -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.4" + Task = "Ensure CUPS is not installed" + Test = { + $test1 = dpkg -s cups + $test1 = $? + if($test1 -match "False"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.5" + Task = "Ensure DHCP Server is not installed" + Test = { + $test1 = dpkg -l | grep -o isc-dhcp-server + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.6" + Task = "Ensure LDAP server is not installed" + Test = { + $test1 = dpkg -l | grep -o slapd + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.7" + Task = "Ensure NFS is not installed" + Test = { + $test1 = dpkg -l | grep -o nfs-kernel-server + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.8" + Task = "Ensure DNS Server is not installed" + Test = { + $test1 = dpkg -l | grep -o bind9 + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.9" + Task = "Ensure FTP Server is not installed" + Test = { + $test1 = dpkg -l | grep -o vsftpd + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.10" + Task = "Ensure HTTP server is not installed" + Test = { + $test1 = dpkg -l | grep -o apache2 + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.11" + Task = "Ensure IMAP and POP3 server are not installed" + Test = { + $test1 = dpkg -l | grep -o dovecot-imapd + $test2 = dpkg -l | grep -o dovecot-pop3d + if($test1 -eq $null -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.12" + Task = "Ensure Samba is not installed" + Test = { + dpkg -s samba | grep -E '(Status:|not installed)' + $test1 = $? + if($test1 -match "False"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.13" + Task = "Ensure HTTP Proxy Server is not installed" + Test = { + $test1 = dpkg -l | grep -o squid + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.14" + Task = "Ensure SNMP Server is not installed" + Test = { + $test1 = dpkg -l | grep -o snmpd + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.15" + Task = "Ensure mail transfer agent is configured for local-only mode" + Test = { + $test1 = ss -lntu | grep -E ':25\s' | grep -E -v '\s(127.0.0.1|::1):25\s' + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.16" + Task = "Ensure rsync service is not installed" + Test = { + dpkg -s rsync | grep -E '(Status:|not installed)' + $test1 = $? + if($test1 -match "False"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.1.17" + Task = "Ensure NIS Server is not installed" + Test = { + $test1 = dpkg -s nis + $test1 = $? + if($test1 -match "False"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.1" + Task = "Ensure NIS Client is not installed" + Test = { + $test1 = dpkg -s nis + $test1 = $? + if($test1 -match "False"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "Ensure rsh client is not installed" + Test = { + $test1 = dpkg -s rsh-client + $test1 = $? + if($test1 -match "False"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.3" + Task = "Ensure talk client is not installed" + Test = { + $test1 = dpkg -s talk + $test1 = $? + if($test1 -match "False"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.4" + Task = "Ensure telnet client is not installed" + Test = { + $test1 = dpkg -l | grep -o telnet + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.5" + Task = "Ensure LDAP client is not installed" + Test = { + $test1 = dpkg -l | grep -o ldap-utils + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.2.6" + Task = "Ensure RPC is not installed" + Test = { + $test1 = dpkg -l | grep -o rpcbind + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "2.3" + Task = "Ensure nonessential services are removed or masked" + Test = { + $test1 = lsof -i -P -n | grep -v "(ESTABLISHED)" + if($test1 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.1.1" + Task = "Disable IPv6" + Test = { + if($isIPv6Disabled -eq $true){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.1.2" + Task = "Ensure wireless interfaces are disabled" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-3.1.2.sh" + $result=bash $path + if($result -match "Wireless is not enabled"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Wireless interfaces are active" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.2.1" + Task = "Ensure packet redirect sending is disabled" + Test = { + $test1 = sysctl net.ipv4.conf.all.send_redirects + $test2 = sysctl net.ipv4.conf.default.send_redirects + $test3 = grep -E "^\s*net\.ipv4\.conf\.all\.send_redirects" /etc/sysctl.conf /etc/sysctl.d/* + $test4 = grep -E "^\s*net\.ipv4\.conf\.default\.send_redirects" /etc/sysctl.conf /etc/sysctl.d/* + if($test1 -match "net.ipv4.conf.all.send_redirects = 0" -and $test2 -match "net.ipv4.conf.default.send_redirects = 0" -and $test3 -match "net.ipv4.conf.all.send_redirects = 0" -and $test4 -match "net.ipv4.conf.default.send_redirects = 0"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.2.2" + Task = "Ensure IP forwarding is disabled" + Test = { + $test1 = sysctl net.ipv4.ip_forward + $test2 = grep -E -s "^\s*net\.ipv4\.ip_forward\s*=\s*1" /etc/sysctl.conf /etc/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /run/sysctl.d/*.conf + if($test1 -match "net.ipv4.ip_forward = 0" -and $test2 -eq $null){ + if($isIPv6Disabled -ne $true){ + $test1 = sysctl net.ipv6.conf.all.forwarding + $test2 = grep -E -s "^\s*net\.ipv6\.conf\.all\.forwarding\s*=\s*1" /etc/sysctl.conf /etc/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /run/sysctl.d/*.conf + if($test1 -match "net.ipv6.conf.all.forwarding = 0" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + else{ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.1" + Task = "Ensure source routed packets are not accepted" + Test = { + $test1 = sysctl net.ipv4.conf.all.accept_source_route + $test2 = sysctl net.ipv4.conf.default.accept_source_route + $test3 = grep "net\.ipv4\.conf\.all\.accept_source_route" /etc/sysctl.conf /etc/sysctl.d/* + $test4 = grep "net\.ipv4\.conf\.default\.accept_source_route" /etc/sysctl.conf /etc/sysctl.d/* + if($test1 -match "net.ipv4.conf.all.accept_source_route = 0" -and $test2 -match "net.ipv4.conf.default.accept_source_route = 0" -and $test3 -match "net.ipv4.conf.all.accept_source_route = 0" -and $test4 -match "net.ipv4.conf.default.accept_source_route = 0"){ + if($isIPv6Disabled -eq $false){ + $test1 = sysctl net.ipv6.conf.all.accept_source_route + $test2 = sysctl net.ipv6.conf.default.accept_source_route + $test3 = grep "net\.ipv6\.conf\.all\.accept_source_route" /etc/sysctl.conf /etc/sysctl.d/* + $test4 = grep "net\.ipv6\.conf\.default\.accept_source_route" /etc/sysctl.conf /etc/sysctl.d/* + if($test1 -match "net.ipv6.conf.all.accept_source_route = 0" -and $test2 -match "net.ipv6.conf.default.accept_source_route = 0" -and $test3 -match "net.ipv4.conf.all.accept_source_route = 0" -and $test4 -match "net.ipv6.conf.default.accept_source_route = 0"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + else{ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.2" + Task = "Ensure ICMP redirects are not accepted" + Test = { + $test1 = sysctl net.ipv4.conf.all.accept_redirects + $test2 = sysctl net.ipv4.conf.default.accept_redirects + $test3 = grep "net\.ipv4\.conf\.all\.accept_redirects" /etc/sysctl.conf /etc/sysctl.d/* + $test4 = grep "net\.ipv4\.conf\.default\.accept_redirects" /etc/sysctl.conf /etc/sysctl.d/* + if($test1 -match "net.ipv4.conf.all.accept_redirects = 0" -and $test2 -match "net.ipv4.conf.default.accept_redirects = 0" -and $test3 -match "net.ipv4.conf.all.accept_redirects = 0" -and $test4 -match "net.ipv4.conf.default.accept_redirects = 0"){ + if($isIPv6Disabled -eq $false){ + $test1 = sysctl net.ipv6.conf.all.accept_redirects + $test2 = sysctl net.ipv6.conf.default.accept_redirects + $test3 = grep "net\.ipv6\.conf\.all\.accept_redirects" /etc/sysctl.conf /etc/sysctl.d/* + $test4 = grep "net\.ipv6\.conf\.default\.accept_redirects" /etc/sysctl.conf /etc/sysctl.d/* + if($test1 -match "net.ipv6.conf.all.accept_redirects = 0" -and $test2 -match "net.ipv6.conf.default.accept_redirects = 0" -and $test3 -match "net.ipv6.conf.all.accept_redirects = 0" -and $test4 -match "net.ipv6.conf.default.accept_redirects = 0"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + else{ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.3" + Task = "Ensure secure ICMP redirects are not accepted" + Test = { + $test1 = sysctl net.ipv4.conf.all.secure_redirects + $test2 = sysctl net.ipv4.conf.default.secure_redirects + $test3 = grep "net\.ipv4\.conf\.all\.secure_redirects" /etc/sysctl.conf /etc/sysctl.d/* + $test4 = grep "net\.ipv4\.conf\.default\.secure_redirects" /etc/sysctl.conf /etc/sysctl.d/* + if($test1 -match "net.ipv4.conf.all.secure_redirects = 0" -and $test2 -match "net.ipv4.conf.default.secure_redirects = 0" -and $test3 -match "net.ipv4.conf.all.secure_redirects = 0" -and $test4 -match "net.ipv4.conf.default.secure_redirects = 0"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.4" + Task = "Ensure suspicious packets are logged" + Test = { + $test1 = sysctl net.ipv4.conf.all.log_martians + $test2 = sysctl net.ipv4.conf.default.log_martians + $test3 = grep "net\.ipv4\.conf\.all\.log_martians" /etc/sysctl.conf /etc/sysctl.d/* + $test4 = grep "net\.ipv4\.conf\.default\.log_martians" /etc/sysctl.conf /etc/sysctl.d/* + if($test1 -match "net.ipv4.conf.all.log_martians = 1" -and $test2 -match "net.ipv4.conf.default.log_martians = 1" -and $test3 -match "net.ipv4.conf.all.log_martians = 1" -and $test4 -match "net.ipv4.conf.default.log_martians = 1"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} + +[AuditTest] @{ + Id = "3.3.5" + Task = "Ensure broadcast ICMP requests are ignored" + Test = { + $test1 = sysctl net.ipv4.icmp_echo_ignore_broadcasts + $test2 = grep "net\.ipv4\.icmp_echo_ignore_broadcasts" /etc/sysctl.conf /etc/sysctl.d/* + if($test1 -match "net.ipv4.icmp_echo_ignore_broadcasts = 1" -and $test2 -match "net.ipv4.icmp_echo_ignore_broadcasts = 1"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.6" + Task = "Ensure bogus ICMP responses are ignored" + Test = { + $test1 = sysctl net.ipv4.icmp_ignore_bogus_error_responses + $test2 = grep "net.ipv4.icmp_ignore_bogus_error_responses" /etc/sysctl.conf /etc/sysctl.d/* + if($test1 -match "net.ipv4.icmp_ignore_bogus_error_responses = 1" -and $test2 -match "net.ipv4.icmp_ignore_bogus_error_responses = 1"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.7" + Task = "Ensure Reverse Path Filtering is enabled" + Test = { + $test1 = sysctl net.ipv4.conf.all.rp_filter + $test2 = sysctl net.ipv4.conf.default.rp_filter + $test3 = grep "net\.ipv4\.conf\.all\.rp_filter" /etc/sysctl.conf /etc/sysctl.d/* + $test4 = grep "net\.ipv4\.conf\.default\.rp_filter" /etc/sysctl.conf /etc/sysctl.d/* + if($test1 -match "net.ipv4.conf.all.rp_filter = 1" -and $test2 -match "net.ipv4.conf.default.rp_filter = 1" -and $test3 -match "net.ipv4.conf.all.rp_filter=1" -and $test4 -match "net.ipv4.conf.default.rp_filter=1"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.8" + Task = "Ensure TCP SYN Cookies is enabled" + Test = { + $test1 = sysctl net.ipv4.tcp_syncookies + $test2 = grep "net\.ipv4\.tcp_syncookies" /etc/sysctl.conf /etc/sysctl.d/* + if($test1 -match "net.ipv4.tcp_syncookies = 1" -and $test2 -match "net.ipv4.tcp_syncookies = 1"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.3.9" + Task = "Ensure IPv6 router advertisements are not accepted" + Test = { + $test1 = sysctl net.ipv6.conf.all.accept_ra + $test2 = sysctl net.ipv6.conf.default.accept_ra + $test3 = grep "net\.ipv6\.conf\.all\.accept_ra" /etc/sysctl.conf /etc/sysctl.d/* + $test4 = grep "net\.ipv6\.conf\.default\.accept_ra" /etc/sysctl.conf /etc/sysctl.d/* + if($test1 -match "net.ipv6.conf.all.accept_ra = 0" -and $test2 -match "net.ipv6.conf.default.accept_ra = 0" -and $test3 -match "net.ipv6.conf.all.accept_ra = 0" -and $test4 -match "net.ipv6.conf.default.accept_ra = 0"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.4.1" + Task = "Ensure DCCP is disabled" + Test = { + $test1 = modprobe -n -v dccp + $test2 = lsmod | grep dccp + if($test1 -match "install /bin/true" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.4.2" + Task = "Ensure SCTP is disabled" + Test = { + $test1 = modprobe -n -v sctp | grep -E '(sctp|install)' + $test2 = lsmod | grep sctp + if($test1 -match "install /bin/true" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.4.3" + Task = "Ensure RDS is disabled" + Test = { + $test1 = modprobe -n -v rds + $test2 = lsmod | grep rds + if($test1 -match "install /bin/true" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.4.4" + Task = "Ensure TIPC is disabled" + Test = { + $test1 = modprobe -n -v tipc | grep -E '(tipc|install)' + $test2 = lsmod | grep tipc + if($test1 -match "install /bin/true" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.1.1" + Task = "Ensure ufw is installed" + Test = { + $test1 = dpkg -s ufw | grep 'Status: install' + if($test1 -match "Status: install ok installed"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.1.2" + Task = "Ensure iptables-persistent is not installed with ufw" + Test = { + $test1 = dpkg -l | grep -o iptables-persistent + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.1.3" + Task = "Ensure ufw service is enabled" + Test = { + $test1 = systemctl is-enabled ufw + $test1 = $? + $test2 = ufw status | grep Status + if($test1 -match "True" -and $test2 -match "Status: active"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.1.4" + Task = "Ensure ufw loopback traffic is configured" + Test = { + $test1 = ufw status verbose + $result1 = $test1 -match "^Anywhere on lo\s+ALLOW IN\s+Anywhere$" + $result2 = $test1 -match "^Anywhere\s+DENY IN\s+127.0.0.0/8$" + $result3 = $test1 -match "^Anywhere (v6) on lo\s+ALLOW IN\s+Anywhere (v6)$" + $result4 = $test1 -match "^Anywhere (v6)\s+DENY IN\s+::1$" + $result5 = $test1 -match "^Anywhere\s+ALLOW OUT\s+Anywhere on lo$" + $result6 = $test1 -match "^Anywhere (v6)\s+ALLOW OUT\s+Anywhere (v6) on lo$" + if($result1 -ne $null -and $result2 -ne $null -and $result3 -ne $null -and $result4 -ne $null -and $result5 -ne $null -and $result6 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.1.5" + Task = "Ensure ufw outbound connections are configured" + Test = { + $test1 = ufw status numbered + if($test1 -notmatch "Status: inactive"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.1.7" + Task = "Ensure ufw default deny firewall policy" + Test = { + $test1 = ufw status verbose + if($test1 -match "deny" -or $test1 -match "reject"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.2.1" + Task = "Ensure nftables is installed" + Test = { + $test1 = dpkg -l | grep -o nftables + if($test1 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.2.2" + Task = "Ensure ufw is uninstalled or disabled with nftables" + Test = { + $test1 = dpkg-query -s ufw + $test1 = $? + $test2 = dpkg-query -s nftables + $test2 = $? + if($test1 -match "True" -and $test2 -match "True"){ + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "3.5.2.3" + Task = "Ensure iptables are flushed with nftables" + Test = { + $test1 = iptables -L + $test2 = ip6tables -L + if($test1 -notmatch "target" -and $test2 -notmatch "target"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.2.4" + Task = "Ensure a nftables table exists" + Test = { + try{ + $test1 = nft list tables + if($test1 -match "table"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "3.5.2.5" + Task = "Ensure nftables base chains exist" + Test = { + try{ + $test1 = nft list ruleset | grep 'hook input' + $test2 = nft list ruleset | grep 'hook forward' + $test3 = nft list ruleset | grep 'hook output' + if($test1 -match "type filter hook input" -and $test2 -match "type filter hook forward" -and $test3 -match "type filter hook output"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "3.5.2.6" + Task = "Ensure nftables loopback traffic is configured" + Test = { + try{ + if($isIPv6Disabled -ne $true){ + $test1 = nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept' + $test2 = nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr' + if($test1 -match 'iif "lo" accept' -and $test2 -match "ip saddr 127.0.0.0/8 counter packets 0 bytes 0 drop"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + else{ + $test = nft list ruleset | awk '/hook input/,/}/' | grep 'ip6 saddr' + if($test -match 'ip6 saddr ::1 counter packets 0 bytes 0 drop'){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "3.5.2.7" + Task = "Ensure nftables outbound and established connections are configured" + Test = { + try{ + $test1 = nft list ruleset | awk '/hook input/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + $test2 = nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + if($test1 -match "ip protocol tcp ct state established accept" -and $test1 -match "p protocol udp ct state established accept" -and $test1 -match "ip protocol icmp ct state established accept" -and $test2 -match "ip protocol tcp ct state established,related,new accep" -and $test2 -match "ip protocol udp ct state established,related,new accept" -and $test2 -match "ip protocol icmp ct state established,related,new accept"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "3.5.2.8" + Task = "Ensure nftables default deny firewall policy" + Test = { + try{ + $test1 = nft list ruleset | grep 'hook input' + $test2 = nft list ruleset | grep 'hook forward' + $test3 = nft list ruleset | grep 'hook output' + if($test1 -match "policy drop" -and $test2 -match "policy drop" -and $test3 -match "policy drop"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "3.5.2.9" + Task = "Ensure nftables service is enabled" + Test = { + $test1 = systemctl is-enabled nftables + if($test1 -match "enabled"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.3.1.1" + Task = "Ensure iptables packages are installed" + Test = { + $test1 = apt list iptables iptables-persistent + $test1 = $? + if($test1 -match "True"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.3.1.2" + Task = "Ensure nftables is not installed with iptables" + Test = { + $test1 = dpkg -s nftables + if($test1 -match "package 'nftables' is not installed"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.3.1.3" + Task = "Ensure ufw is uninstalled or disabled with iptables" + Test = { + $test1 = dpkg -l | grep -o ufw + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.3.2.1" + Task = "Ensure iptables loopback traffic is configured" + Test = { + $test1 = iptables -L INPUT -v -n | grep "Chain\s*INPUT\s*(policy\s*DROP" + $test2 = iptables -L OUTPUT -v -n | grep "Chain\s*OUTPUT\s*(policy\s*DROP" + if($test1 -ne $null -and $test2 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.3.2.2" + Task = "Ensure iptables outbound and established connections are configured" + Test = { + $test1 = iptables -L -v -n + if($test1 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.3.2.3" + Task = "Ensure iptables default deny firewall policy" + Test = { + $output = iptables -L + $test1 = $output -match "DROP" | grep "Chain INPUT (policy DROP)" + $res1 = $? + $test2 = $output -match "DROP" | grep "Chain FORWARD (policy DROP)" + $res2 = $? + $test3 = $output -match "DROP" | grep "Chain OUTPUT (policy DROP)" + $res3 = $? + if($res1 -match "True" -and $res2 -match "True" -and $res3 -match "True"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.5.3.3.3" + Task = "Ensure ip6tables default deny firewall policy" + Test = { + $output = ip6tables -L + $test1 = $output -match "DROP" | grep "Chain INPUT (policy DROP)" + $res1 = $? + $test2 = $output -match "DROP" | grep "Chain FORWARD (policy DROP)" + $res2 = $? + $test3 = $output -match "DROP" | grep "Chain OUTPUT (policy DROP)" + $res3 = $? + if($isIPv6Disabled -eq $true){ + return @{ + Message = "Compliant" + Status = "True" + } + } + if($res1 -match "True" -and $res2 -match "True" -and $res3 -match "True"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.1.1" + Task = "Ensure auditd is installed" + Test = { + $test1 = dpkg -l | grep -o auditd + $test2 = dpkg -l | grep -o audispd-plugins + if($test1 -ne $null -and $test2 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.1.2" + Task = "Ensure auditd service is enabled" + Test = { + $test1 = systemctl is-enabled auditd + if($test1 -match "enabled"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.1.3" + Task = "Ensure auditing for processes that start prior to auditd is enabled" + Test = { + $test1 = grep "^\s*linux" /boot/grub/grub.cfg | grep -v "audit=1" + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.1.4" + Task = "Ensure audit_backlog_limit is sufficient" + Test = { + $test1 = grep "^\s*linux" /boot/grub/grub.cfg | grep -v "audit_backlog_limit=" + $test2 = grep "^\s*linux" /boot/grub/grub.cfg | grep "audit_backlog_limit=" | sed 's/^.*\(audit_backlog_limit=[\/a-z]*\).*$/\1/' | cut -f2 -d'=' + $test2 = [int] $test2 + if($test1 -eq $null -and $test2 -ge 8192){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.2.1" + Task = "Ensure audit log storage size is configured" + Test = { + $test1 = grep max_log_file /etc/audit/auditd.conf + if($test1 -match "max_log_file"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.2.2" + Task = "Ensure audit logs are not automatically deleted" + Test = { + $test1 = grep max_log_file_action /etc/audit/auditd.conf + if($test1 -match "max_log_file_action = keep_logs"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.1.2.3" + Task = "Ensure system is disabled when audit logs are full" + Test = { + $test1 = grep space_left_action /etc/audit/auditd.conf + $test2 = grep action_mail_acct /etc/audit/auditd.conf + $test3 = grep admin_space_left_action /etc/audit/auditd.conf + if($test1 -match "space_left_action = email" -and $test2 -match "action_mail_acct = root" -and $test3 -match "admin_space_left_action = halt"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} + +[AuditTest] @{ + Id = "4.1.3" + Task = "Ensure events that modify date and time information are collected" + Test = { + try{ + $bitVersion = uname -a + #if 32 bit + if($bitVersion -match "i386"){ + $output = grep time-change /etc/audit/rules.d/*.rules + $test1 = $output -match "-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change" + $test2 = $output -match "-a always,exit -F arch=b32 -S clock_settime -k time-change" + $test3 = $output -match "-w /etc/localtime -p wa -k time-change" + + $output2 = auditctl -l | grep time-change + $test4 = $output2 -match "-a always,exit -F arch=b32 -S stime,settimeofday,adjtimex -F key=time-change" + $test5 = $output2 -match "-a always,exit -F arch=b32 -S clock_settime -F key=time-change" + $test6 = $output2 -match "-w /etc/localtime -p wa -k time-change" + + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null -and $test5 -ne $null -and $test6 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + #64 bit + elseif($bitVersion -match "x86_64"){ + $output = grep time-change /etc/audit/rules.d/*.rules + $test1 = $output -match "-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change" + $test2 = $output -match "-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change" + $test3 = $output -match "-a always,exit -F arch=b64 -S clock_settime -k time-change" + $test4 = $output -match "-a always,exit -F arch=b32 -S clock_settime -k time-change" + $test5 = $output -match "-w /etc/localtime -p wa -k time-change" + $output2 = auditctl -l | grep time-change + $test6 = $output2 -match "-a always,exit -F arch=b64 -S adjtimex,settimeofday -F key=time-change" + $test7 = $output2 -match "-a always,exit -F arch=b32 -S stime,settimeofday,adjtimex -F key=time-change" + $test8 = $output2 -match "-a always,exit -F arch=b64 -S clock_settime -F key=time-change" + $test9 = $output2 -match "-a always,exit -F arch=b32 -S clock_settime -F key=time-change" + $test10 = $output2 -match "-w /etc/localtime -p wa -k time-change" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null -and $test5 -ne $null -and $test6 -ne $null -and $test7 -ne $null -and $test8 -ne $null -and $test9 -ne $null -and $test10 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.4" + Task = "Ensure events that modify user/group information are collected" + Test = { + try{ + $output = grep identity /etc/audit/rules.d/*.rules + $test1 = $output -match "-w /etc/group -p wa -k identity" + $test2 = $output -match "-w /etc/passwd -p wa -k identity" + $test3 = $output -match "-w /etc/gshadow -p wa -k identity" + $test4 = $output -match "-w /etc/shadow -p wa -k identity" + $test5 = $output -match "-w /etc/security/opasswd -p wa -k identity" + $output2 = auditctl -l | grep identity + $test6 = $output2 -match "-w /etc/group -p wa -k identity" + $test7 = $output2 -match "-w /etc/passwd -p wa -k identity" + $test8 = $output2 -match "-w /etc/gshadow -p wa -k identity" + $test9 = $output2 -match "-w /etc/shadow -p wa -k identity" + $test10 = $output2 -match "-w /etc/security/opasswd -p wa -k identity" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null -and $test5 -ne $null -and $test6 -ne $null -and $test7 -ne $null -and $test8 -ne $null -and $test9 -ne $null -and $test10 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.5" + Task = "Ensure events that modify the system's network environment are collected" + Test = { + try{ + $bitVersion = uname -a + #if 32 bit + if($bitVersion -match "i386"){ + $output = grep system-locale /etc/audit/rules.d/*.rules + $test1 = $output -match "-a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale" + $test2 = $output -match "-w /etc/issue -p wa -k system-locale" + $test3 = $output -match "-w /etc/issue.net -p wa -k system-locale" + $test4 = $output -match "-w /etc/hosts -p wa -k system-locale" + $test5 = $output -match "-w /etc/network -p wa -k system-locale" + $output2 = auditctl -l | grep system-locale + $test6 = $output2 -match "-a always,exit -F arch=b32 -S sethostname,setdomainname -F key=system-locale" + $test7 = $output2 -match "-w /etc/issue -p wa -k system-locale" + $test8 = $output2 -match "-w /etc/issue.net -p wa -k system-locale" + $test9 = $output2 -match "-w /etc/hosts -p wa -k system-locale" + $test10 = $output2 -match "-w /etc/network -p wa -k system-locale" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null -and $test5 -ne $null -and $test6 -ne $null -and $test7 -ne $null -and $test8 -ne $null -and $test9 -ne $null -and $test10 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + #64 bit + elseif($bitVersion -match "x86_64"){ + $output = grep system-locale /etc/audit/rules.d/*.rules + $test1 = $output -match "-a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale" + $test1_2 = $output -match "-a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale" + $test2 = $output -match "-w /etc/issue -p wa -k system-locale" + $test3 = $output -match "-w /etc/issue.net -p wa -k system-locale" + $test4 = $output -match "-w /etc/hosts -p wa -k system-locale" + $test5 = $output -match "-w /etc/network -p wa -k system-locale" + $output2 = auditctl -l | grep system-locale + $test6 = $output2 -match "-a always,exit -F arch=b64 -S sethostname,setdomainname -F key=system-locale" + $test6_2 = $output2 -match "-a always,exit -F arch=b32 -S sethostname,setdomainname -F key=system-locale" + $test7 = $output2 -match "-w /etc/issue -p wa -k system-locale" + $test8 = $output2 -match "-w /etc/issue.net -p wa -k system-locale" + $test9 = $output2 -match "-w /etc/hosts -p wa -k system-locale" + $test10 = $output2 -match "-w /etc/network -p wa -k system-locale" + if($test1 -ne $null -and $test1_2 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null -and $test5 -ne $null -and $test6 -ne $null -and $test6_2 -ne $null -and $test7 -ne $null -and $test8 -ne $null -and $test9 -ne $null -and $test10 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.6" + Task = "Ensure events that modify the system's Mandatory Access Controls are collected" + Test = { + try{ + $output = grep MAC-policy /etc/audit/rules.d/*.rules + $test1 = $output -match "-w /etc/apparmor/ -p wa -k MAC-policy" + $test2 = $output -match "-w /etc/apparmor.d/ -p wa -k MAC-policy" + $output2 = auditctl -l | grep MAC-policy + $test3 = $output2 -match "-w /etc/apparmor -p wa -k MAC-policy" + $test4 = $output2 -match "-w /etc/apparmor.d -p wa -k MAC-policy" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.7" + Task = "Ensure login and logout events are collected" + Test = { + try{ + $output = grep logins /etc/audit/rules.d/*.rules + $test1 = $output -match "-w /var/log/faillog -p wa -k logins" + $test2 = $output -match "-w /var/log/lastlog -p wa -k logins" + $test3 = $output -match "-w /var/log/tallylog -p wa -k logins" + $output2 = auditctl -l | grep logins + $test4 = $output2 -match "-w /var/log/faillog -p wa -k logins" + $test5 = $output2 -match "-w /var/log/lastlog -p wa -k logins" + $test6 = $output2 -match "-w /var/log/tallylog -p wa -k logins" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null -and $test5 -ne $null -and $test6 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.8" + Task = "Ensure session initiation information is collected" + Test = { + try{ + $output = grep -E '(session|logins)' /etc/audit/rules.d/*.rules + $test1 = $output -match "-w /var/run/utmp -p wa -k session" + $test2 = $output -match "-w /var/log/wtmp -p wa -k logins" + $test3 = $output -match "-w /var/log/btmp -p wa -k logins" + $output2 = auditctl -l | grep -E '(session|logins)' + $test4 = $output2 -match "-w /var/run/utmp -p wa -k session" + $test5 = $output2 -match "-w /var/log/wtmp -p wa -k logins" + $test6 = $output2 -match "-w /var/log/btmp -p wa -k logins" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null -and $test5 -ne $null -and $test6 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.9" + Task = "Ensure discretionary access control permission modification events are collected" + Test = { + try{ + $bitVersion = uname -a + #if 32 bit + if($bitVersion -match "i386"){ + $output = grep perm_mod /etc/audit/rules.d/*.rules + $test1 = $output -match "-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod" + $test2 = $output -match "-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod" + $test3 = $output -match "-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295" + $test4 = $output -match "-k perm_mod" + $output2 = auditctl -l | grep perm_mod + $test5 = $output2 -match "-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=-1" + $test6 = $output2 -match "-F key=perm_mod" + $test7 = $output2 -match "-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F auid>=1000 -F auid!=-1 -F key=perm_mod" + $test8 = $output2 -match "-a always,exit -F arch=b32 -S" + $test9 = $output2 -match "setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=-1 -F key=perm_mod" + if($test1 -ne $null -and $test1_2 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null -and $test5 -ne $null -and $test6 -ne $null -and $test6_2 -ne $null -and $test7 -ne $null -and $test8 -ne $null -and $test9 -ne $null){ + + return @{ + Message = "Compliant" + Status = "True" + } + } + } + #64 Bit + elseif($bitVersion -match "x86_64"){ + $output = grep perm_mod /etc/audit/rules.d/*.rules + $test1 = $output -match "-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod" + $test2 = $output -match "-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod" + $test3 = $output -match "-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod" + $test4 = $output -match "-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod" + $test5 = $output -match "-a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295" + $test6 = $output -match "-k perm_mod" + $test7 = $output -match "-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295" + $test8 = $output -match "-k perm_mod" + $output2 = auditctl -l | grep perm_mod + $test9 = $output2 -match "-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=-1 -F key=perm_mod" + $test10 = $output2 -match "-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=-1 -F key=perm_mod" + $test11 = $output2 -match "-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=-1 -F key=perm_mod" + $test12 = $output2 -match "-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F auid>=1000 -F auid!=-1 -F key=perm_mod" + $test13 = $output2 -match "-a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=-1 -F key=perm_mod" + $test14 = $output2 -match "-a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=-1 -F key=perm_mod" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null -and $test5 -ne $null -and $test6 -ne $null -and $test7 -ne $null -and $test8 -ne $null -and $test9 -ne $null -and $test10 -ne $null -and $test11 -ne $null -and $test12 -ne $null -and $test13 -ne $null -and $test14 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.10" + Task = "Ensure unsuccessful unauthorized file access attempts are collected" + Test = { + try{ + $bitVersion = uname -a + if($bitVersion -match "i386"){ + $output = grep access /etc/audit/rules.d/*.rules + $test1 = $output -match "-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access" + $test2 = $output -match "-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access" + $output2 = auditctl -l | grep access + $test3 = $output2 -match "-a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat -F exit=-EACCES -F auid>=1000 -F auid!=-1 -F key=access" + $test4 = $output2 -match "-a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat -F exit=-EPERM -F auid>=1000 -F auid!=-1 -F key=access" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + elseif($bitVersion -match "x86_64"){ + $output = grep access /etc/audit/rules.d/*.rules + $test1 = $output -match "-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access" + $test2 = $output -match "-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access" + $test3 = $output -match "-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access" + $test4 = $output -match "-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access" + $output2 = auditctl -l | grep access + $test5 = $output2 -match "-a always,exit -F arch=b64 -S open,truncate,ftruncate,creat,openat -F exit=-EACCES -F auid>=1000 -F auid!=-1 -F key=access" + $test6 = $output2 -match "-a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat -F exit=-EACCES -F auid>=1000 -F auid!=-1 -F key=access" + $test7 = $output2 -match "-a always,exit -F arch=b64 -S open,truncate,ftruncate,creat,openat -F exit=-EPERM -F auid>=1000 -F auid!=-1 -F key=access" + $test8 = $output2 -match "-a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat -F exit=-EPERM -F auid>=1000 -F auid!=-1 -F key=access" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null -and $test5 -ne $null -and $test6 -ne $null -and $test7 -ne $null -and $test8 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.11" + Task = "Ensure use of privileged commands is collected" + Test = { + $results = @() + $mountPoints = mount | grep -v "/var/lib/snapd" | grep -v "cgroup on " | grep -v "noexec" | grep -v " fuse" | cut -f 3 -d ' ' + foreach($mountPoint in $mountPoints){ + $res=bash -c "find $($mountPoint) -xdev \( -perm -4000 -o -perm -2000 \) -type f" + $results += $res | awk '{print "-a always,exit -F path=" $1 " -F perm=x -F auid>=1000 -F auid!=4294967295 \ -k privileged" }' + } + $viablePaths = @() + $paths = @() + foreach($element in $results){ + $viablePaths += $element | cut -d ' ' -f 4 | cut -d '=' -f 2 | grep "/etc/audit/rules.d/*.rules" + $paths += $element | cut -d ' ' -f 4 | cut -d '=' -f 2 | grep -v "/etc/audit/rules.d/*.rules" + } + $message = "" + foreach($line in $paths){ + $message += "
$line" + } + if($viablePaths.Count -ne $results.Count){ + return @{ + Message = "Not all results are in path /etc/audit/rules.d/ and are .rules files. Non compliant files:
$($message)" + Status = "False" + } + } + return @{ + Message = "Compliant" + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.1.12" + Task = "Ensure successful file system mounts are collected" + Test = { + try{ + $bitVersion = uname -a + if($bitVersion -match "i386"){ + $output = grep mounts /etc/audit/rules.d/*.rules + $test1 = $output -match "-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts" + $output2 = auditctl -l | grep mounts + $test2 = $output2 -match "-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=-1 -F key=mounts" + if($test1 -ne $null -and $test2 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + elseif($bitVersion -match "x86_64"){ + $output = grep mounts /etc/audit/rules.d/*.rules + $test1 = $output -match "-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts" + $test2 = $output -match "-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts" + $output2 = auditctl -l | grep mounts + $test3 = $output2 -match "-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=-1 -F key=mounts" + $test4 = $output2 -match "-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=-1 -F key=mounts" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null -and $test4 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.13" + Task = "Ensure file deletion events by users are collected" + Test = { + try{ + $test1 = grep delete /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep delete + if($test1 -match "-a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete" -and $test2 -match "-a always,exit -F arch=b32 -S unlink,rename,unlinkat,renameat -F auid>=1000 -F auid!=-1 -F key=delete"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.14" + Task = "Ensure changes to system administration scope (sudoers) is collected" + Test = { + try{ + $test1 = grep scope /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep scope + if($test1 -match "-w /etc/sudoers -p wa -k scope" -and $test1 -match "-w /etc/sudoers.d/ -p wa -k scope" -and $test2 -match "-w /etc/sudoers -p wa -k scope" -and $test2 -match "-w /etc/sudoers.d -p wa -k scope" ){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.15" + Task = "Ensure system administrator command executions (sudo) are collected" + Test = { + try{ + $test1 = grep actions /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep actions + $res1 = "-a always,exit -F arch=b64 -C euid!=uid -F euid=0 -Fauid>=1000 -F auid!=4294967295 -S execve -k actions" + $res2 = "-a always,exit -F arch=b32 -C euid!=uid -F euid=0 -Fauid>=1000 -F auid!=4294967295 -S execve -k actions" + $res3 = "-a always,exit -F arch=b64 -S execve -C uid!=euid -F euid=0 -F auid>=1000 -F auid!=-1 -F key=actions" + $res4 = "-a always,exit -F arch=b32 -S execve -C uid!=euid -F euid=0 -F auid>=1000 -F auid!=-1 -F key=actions" + if($test1 -match $res1 -and $test1 -match $res2 -and $test2 -match $res3 -and $test2 -match $res4){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.16" + Task = "Ensure kernel module loading and unloading is collected" + Test = { + $test1 = grep modules /etc/audit/rules.d/*.rules + $test2 = auditctl -l | grep modules + $res1 = "-w /sbin/insmod -p x -k modules" + $res2 = "-w /sbin/rmmod -p x -k modules" + $res3 = "-w /sbin/modprobe -p x -k modules" + $res4 = "-a always,exit -F arch=b64 -S init_module -S delete_module -k modules" + $res5 = "-w /sbin/insmod -p x -k modules" + $res6 = "-w /sbin/rmmod -p x -k modules" + $res7 = "-w /sbin/modprobe -p x -k modules" + $res8 = "-a always,exit -F arch=b64 -S init_module,delete_module -F key=modules" + + if($test1 -match $res1 -and $test1 -match $res2 -and $test1 -match $res3 -and $test1 -match $res4 -and $test2 -match $res5 -and $test2 -match $res6 -and $test2 -match $res7 -and $test2 -match $res8){ + return @{ + Message = "Compliant" + Status = "True" + } + } + else{ + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.1.17" + Task = "Ensure the audit configuration is immutable" + Test = { + $test1 = grep "^\s*[^#]" /etc/audit/rules.d/*.rules | tail -l + if($test1 -match "-e 2"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.1.1" + Task = "Ensure rsyslog is installed" + Test = { + $test1 = dpkg -s rsyslog + if($test1 -match "Status: install ok installed"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.1.2" + Task = "Ensure rsyslog Service is enabled" + Test = { + $test1 = systemctl is-enabled rsyslog + if($test1 -match "enabled"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.1.3" + Task = "Ensure logging is configured" + Test = { + $logginTypes = 0 + $fileContent = cat /etc/rsyslog.conf /etc/rsyslog.d/*.conf + if($fileContent -match "^*.emerg\s*:omusrmsg:*") {$logginTypes++} + if($fileContent -match "^auth,authpriv.*\s*/var/log/auth.log") {$logginTypes++} + if($fileContent -match "^mail.*\s*-/var/log/mail") {$logginTypes++} + if($fileContent -match "^mail.info\s*-/var/log/mail.info") {$logginTypes++} + if($fileContent -match "^mail.warning\s*-/var/log/mail.warn") {$logginTypes++} + if($fileContent -match "^mail.err\s*/var/log/mail.err") {$logginTypes++} + if($fileContent -match "^news.crit\s*-/var/log/news/news.crit") {$logginTypes++} + if($fileContent -match "^news.err\s*-/var/log/news/news.err") {$logginTypes++} + if($fileContent -match "^news.notice\s*-/var/log/news/news.notice") {$logginTypes++} + if($fileContent -match "^*.=warning;*.=err\s*-/var/log/warn") {$logginTypes++} + if($fileContent -match "^*.crit\s*/var/log/warn") {$logginTypes++} + if($fileContent -match "^*.*;mail.none;news.none\s*-/var/log/messages") {$logginTypes++} + if($fileContent -match "^local0,local1.*\s*-/var/log/localmessages") {$logginTypes++} + if($fileContent -match "^local2,local3.*\s*-/var/log/localmessages") {$logginTypes++} + if($fileContent -match "^local4,local5.*\s*-/var/log/localmessages") {$logginTypes++} + if($fileContent -match "^local6,local7.*\s*-/var/log/localmessages") {$logginTypes++} + + if($logginTypes -le 5){ + return @{ + Message = "Not enough logging types supported! Currently: " + $logginTypes + Status = "False" + } + } + if($logginTypes -le 12){ + return @{ + Message = "Currently configured: " + $logginTypes + Status = "Warning" + } + } + return @{ + Message = "Compliant. Currently: " + $logginTypes + Status = "True" + } + } +} +[AuditTest] @{ + Id = "4.2.1.4" + Task = "Ensure rsyslog default file permissions configured" + Test = { + $test1 = cat /etc/rsyslog.conf /etc/rsyslog.d/*.conf | grep "^\s*\`$FileCreateMode" + if($test1 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +# [AuditTest] @{ +# Id = "4.2.1.5" +# Task = "Ensure rsyslog is configured to send logs to a remote log host" +# Test = { +# $test1 = grep -E '^\s*([^#]+\s+)?action\(([^#]+\s+)?\btarget=\"?[^#"]+\"?\b' /etc/rsyslog.conf /etc/rsyslog.d/*.conf +# grep -E '^\s*([^#]+\s+)?action\(([^#]+\s+)?\btarget=\"?[^#"]+\"?\b' /etc/rsyslog.conf /etc/rsyslog.d/*.conf +# if($test1 -match "target"){ +# return @{ +# Message = "Compliant" +# Status = "True" +# } +# } +# return @{ +# Message = "Not-Compliant" +# Status = "False" +# } +# } +# } +[AuditTest] @{ + Id = "4.2.2.1" + Task = "Ensure journald is configured to send logs to rsyslog" + Test = { + $test1 = grep -e ForwardToSyslog /etc/systemd/journald.conf + if($test1 -match "ForwardToSyslog=yes"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.2.2" + Task = "Ensure journald is configured to compress large log files" + Test = { + $test1 = grep -e Compress /etc/systemd/journald.conf + if($test1 -match "Compress=yes"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.2.3" + Task = "Ensure journald is configured to write logfiles to persistent disk" + Test = { + $test1 = grep -e Storage /etc/systemd/journald.conf + if($test1 -match "Storage=persistent"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.2.3" + Task = "Ensure permissions on all logfiles are configured" + Test = { + $fileListAll = find /var/log -type f -ls + $fileListFiltered = find /var/log -type f -ls | grep "\-....\-\-\-\-\-" + if($fileListAll.Count -eq $fileListFiltered.Count){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "$($fileListAll.Count - $fileListFiltered.Count) files grant too many permissions" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "4.3" + Task = "Ensure logrotate is configured" + Test = { + return @{ + Message = "Review /etc/logrotate.conf and /etc/logrotate.d/rsyslog and verify logs are rotated according to site policy." + Status = "None" + } + } +} +[AuditTest] @{ + Id = "4.4" + Task = "Ensure logrotate assigns appropriate permissions" + Test = { + $test1 = grep -Es "^\s*create\s+\S+" /etc/logrotate.conf /etc/logrotate.d/* | grep -E -v "\s(0)?[0-6][04]0\s" + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.1" + Task = "Ensure cron daemon is enabled and running" + Test = { + $test1 = systemctl is-enabled cron + $test2 = systemctl status cron | grep 'Active: active (running) ' + if($test1 -eq "enabled" -and $test2 -match "running"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.2" + Task = "Ensure permissions on /etc/crontab are configured" + Test = { + $test1 = stat /etc/crontab + if($test1 -eq "Access: (0600/-rw-------)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.3" + Task = "Ensure permissions on /etc/cron.hourly are configured" + Test = { + $test1 = stat /etc/cron.hourly/ + if($test1 -eq "Access: (0700/drwx------)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.4" + Task = "Ensure permissions on /etc/cron.daily are configured" + Test = { + $test1 = stat /etc/cron.daily/ + if($test1 -eq "Access: (0700/drwx------)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.5" + Task = "Ensure permissions on /etc/cron.weekly are configured" + Test = { + $test1 = stat /etc/cron.weekly/ + if($test1 -eq "Access: (0700/drwx------)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.6" + Task = "Ensure permissions on /etc/cron.monthly are configured" + Test = { + $test1 = stat /etc/cron.monthly/ + if($test1 -eq "Access: (0700/drwx------)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.7" + Task = "Ensure permissions on /etc/cron.d are configured" + Test = { + $test1 = stat /etc/cron.d/ + if($test1 -eq "Access: (0700/drwx------)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.8" + Task = "Ensure cron is restricted to authorized users" + Test = { + $test1 = stat /etc/cron.deny + $test1 = $? + $test2 = stat /etc/cron.allow + if($test1 -match "False" -and $test2 -match "Access: (0640/-rw-r-----)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.1.9" + Task = "Ensure at is restricted to authorized users" + Test = { + $test1 = stat /etc/at.deny + $test1 = $? + $test2 = stat /etc/at.allow | grep 0640 + if($test1 -match "False" -and $test2 -eq "Access: (0640/-rw-r-----)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.1" + Task = "Ensure sudo is installed" + Test = { + $test1 = dpkg -s sudo + if($test1 -match "Status: install ok installed"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.2" + Task = "Ensure sudo commands use pty" + Test = { + $test1 = grep -Ei '^\s*Defaults\s+([^#]+,\s*)?use_pty(,\s+\S+\s*)*(\s+#.*)?$' /etc/sudoers /etc/sudoers.d/* + if($test1 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.2.3" + Task = "Ensure sudo log file exists" + Test = { + $test1 = grep -Ei '^\s*Defaults\s+logfile=\S+' /etc/sudoers /etc/sudoers.d/* + if($test1 -ne $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.3.1" + Task = "Ensure permissions on /etc/ssh/sshd_config are configured" + Test = { + try{ + try{ + $test1 = stat /etc/ssh/sshd_config | grep 0600 + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + + if($test1 -eq "Access: (0600/-rw-------)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.2" + Task = "Ensure permissions on SSH private host key files are configured" + Test = { + $res = bash -c "find /etc/ssh -xdev -type f -name 'ssh_host_*_key' -exec stat {} \;" | grep "Access:\s*(0600/-rw-------)\s*Uid:\s*(\s*0/\s*root)\s*Gid:\s*(\s*0/\s*root)\s*" + if($res.count -eq 3){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.3.3" + Task = "Ensure permissions on SSH public host key files are configured" + Test = { + $res = bash -c "find /etc/ssh -xdev -type f -name 'ssh_host_*_key.pub' -exec stat {} \;" | grep "Access:\s*(0644/-rw-r--r--)\s*Uid:\s*(\s*0/\s*root)\s*Gid:\s*(\s*0/\s*root)\s*" + if($res.count -eq 3){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.3.4" + Task = "Ensure SSH access is limited" + Test = { + try{ + $result = bash -c "sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -Ei '^\s*(allow|deny)(users|groups)\s+\S+'" + if($result -match "allowusers" -or $result -match "allowgroups" -or $result -match "denyusers" -or $result -match "denygroups"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.5" + Task = "Ensure SSH LogLevel is appropriate" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep loglevel + try{ + $test2 = grep -is 'loglevel' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf | grep -Evi '(VERBOSE|INFO)' + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if(($test1 -match "loglevel VERBOSE" -or $test1 -match "loglevel INFO") -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.6" + Task = "Ensure SSH X11 forwarding is disabled" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i x11forwarding + try{ + $test2 = grep -Eis '^\s*x11forwarding\s+yes' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -match "x11forwarding no" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.7" + Task = "Ensure SSH MaxAuthTries is set to 4 or less" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep maxauthtries | cut -d ' ' -f 2 + try{ + $test2 = grep -Eis '^\s*maxauthtries\s+([5-9]|[1-9][0-9]+)' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -le 4 -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.8" + Task = "Ensure SSH IgnoreRhosts is enabled" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep ignorerhosts + try{ + $test2 = grep -Eis '^\s*ignorerhosts\s+no\b' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -match "ignorerhosts yes" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.10" + Task = "Ensure SSH root login is disabled" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permitrootlogin + try{ + $test2 = grep -Eis '^\s*PermitRootLogin\s+yes' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -match "permitrootlogin no" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.11" + Task = "Ensure SSH PermitEmptyPasswords is disabled" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permitemptypasswords + try{ + $test2 = grep -Eis '^\s*PermitEmptyPasswords\s+yes' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -match "permitemptypasswords no" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.12" + Task = "Ensure SSH PermitUserEnvironment is disabled" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permituserenvironment + try{ + $test2 = grep -Eis '^\s*PermitUserEnvironment\s+yes' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -match "permituserenvironment no" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.13" + Task = "Ensure only strong Ciphers are used" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -Ei '^\s*ciphers\s+([^#]+,)?(3des-cbc|aes128-cbc|aes192-cbc|aes256-cbc|arcfour|arcfour128|arcfour256|blowfish-cbc|cast128-cbc|rijndael-cbc@lysator.liu.se)\b' + try{ + $test2 = grep -Eis '^\s*ciphers\s+([^#]+,)?(3des-cbc|aes128-cbc|aes192-cbc|aes256-cbc|arcfour|arcfour128|arcfour256|blowfish-cbc|cast128-cbc|rijndael-cbc@lysator.liu.se)\b' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -eq $null -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.14" + Task = "Ensure only strong MAC algorithms are used" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -Ei '^\s*macs\s+([^#]+,)?(hmac-md5|hmac-md5-96|hmac-ripemd160|hmac-sha1|hmac-sha1-96|umac-64@openssh\.com|hmac-md5-etm@openssh\.com|hmac-md5-96-etm@openssh\.com|hmac-ripemd160-etm@openssh\.com|hmac-sha1-etm@openssh\.com|hmac-sha1-96-etm@openssh\.com|umac-64-etm@openssh\.com|umac-128-etm@openssh\.com)\b' + try{ + $test2 = grep -Eis '^\s*macs\s+([^#]+,)?(hmac-md5|hmac-md5-96|hmac-ripemd160|hmac-sha1|hmac-sha1-96|umac-64@openssh\.com|hmac-md5-etm@openssh\.com|hmac-md5-96-etm@openssh\.com|hmac-ripemd160-etm@openssh\.com|hmac-sha1-etm@openssh\.com|hmac-sha1-96-etm@openssh\.com|umac-64-etm@openssh\.com|umac-128-etm@openssh\.com)\b' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -eq $null -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.15" + Task = "Ensure only strong Key Exchange algorithms are used" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -Ei'^\s*kexalgorithms\s+([^#]+,)?(diffie-hellman-group1-sha1|diffie-hellman-group14-sha1|diffie-hellman-group-exchange-sha1)\b' + try{ + $test2 = grep -Ei '^\s*kexalgorithms\s+([^#]+,)?(diffie-hellman-group1-sha1|diffie-hellman-group14-sha1|diffie-hellman-group-exchange-sha1)\b' /etc/ssh/sshd_config + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -eq $null -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.16" + Task = "Ensure SSH Idle Timeout Interval is configured" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep clientaliveinterval | cut -d ' ' -f 2 + $test2 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep clientalivecountmax | cut -d ' ' -f 2 + try{ + $test3 = grep -Eis '^\s*clientaliveinterval\s+(0|3[0-9][1-9]|[4-9][0-9][0-9]|[1-9][0-9][0-9][0-9]+|[6-9]m|[1-9][0-9]+m)\b' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + $test4 = grep -Eis '^\s*ClientAliveCountMax\s+(0|[4-9]|[1-9][0-9]+)\b' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if(($test1 -ge 1 -and $test1 -le 300) -and ($test2 -ge 1 -and $test2 -le 3) -and $test3 -eq $null -and $test4 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.17" + Task = "Ensure SSH LoginGraceTime is set to one minute or less" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep logingracetime | cut -d ' ' -f 2 + try{ + $test2 = grep -Eis '^\s*LoginGraceTime\s+(0|6[1-9]|[7-9][0-9]|[1-9][0-9][0-9]+|[^1]m)' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if(($test1 -ge 1 -and $test1 -le 60) -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.18" + Task = "Ensure SSH warning banner is configured" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep banner + try{ + $test2 = grep -Eis '^\s*Banner\s+"?none\b' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -match "banner /etc/issue.net" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.19" + Task = "Ensure SSH PAM is enabled" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i usepam + try{ + $test2 = grep -Eis '^\s*UsePAM\s+no' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -match "usepam yes" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.20" + Task = "Ensure SSH AllowTcpForwarding is disabled" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i allowtcpforwarding + try{ + $test2 = grep -Eis '^\s*AllowTcpForwarding\s+yes\b' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -match "allowtcpforwarding no" -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.21" + Task = "Ensure SSH MaxStartups is configured" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i maxstartups + try{ + $test2 = grep -Eis '^\s*maxstartups\s+(((1[1-9]|[1-9][0-9][0-9]+):([0-9]+):([0-9]+))|(([0-9]+):(3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):([0-9]+))|(([0-9]+):([0-9]+):(6[1-9]|[7-9][0-9]|[1-9][0-9][0-9]+)))' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + $value1 = $test1 | cut -d ':' -f 1 + $value2 = $test1 | cut -d ':' -f 2 + $value3 = $test1 | cut -d ':' -f 3 + if($value1 -ge 10 -and $value2 -ge 30 -and $value3 -ge 60 -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.3.22" + Task = "Ensure SSH MaxSessions is limited" + Test = { + try{ + $test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i maxsessions | cut -d ' ' -f 2 + + try{ + $test2 = grep -Eis '^\s*MaxSessions\s+(1[1-9]|[2-9][0-9]|[1-9][0-9][0-9]+)' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf + } + catch{ + return @{ + Message = "Path not found!" + Status = "False" + } + } + if($test1 -le 10 -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command doesn't exist" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.4.1" + Task = "Ensure password creation requirements are configured" + Test = { + $test1 = grep '^\s*minlen\s*' /etc/security/pwquality.conf | cut -d ' ' -f 3 + $test2 = grep '^\s*minclass\s*' /etc/security/pwquality.conf | cut -d ' ' -f 3 + $test3 = grep -E '^\s*password\s+(requisite|required)\s+pam_pwquality\.so\s+(\S+\s+)*retry=[1-3]\s*(\s+\S+\s*)*(\s+#.*)?$' /etc/pam.d/common-password | cut -d '=' -f 2 + if($test1 -ge 14 -and $test2 -eq 4 -and $test3 -le 3){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.4.2" + Task = "Ensure lockout for failed password attempts is configured" + Test = { + $test1 = grep "pam_tally2" /etc/pam.d/common-auth + $test2 = grep -E "pam_(tally2|deny)\.so" /etc/pam.d/common-account + if($test1 -ne $null -and $test2 -match "pam_deny.so" -and $test2 -match "pam_tally2.so"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.4.3" + Task = "Ensure password reuse is limited" + Test = { + $test1 = grep -E '^\s*password\s+required\s+pam_pwhistory\.so\s+([^#]+\s+)?remember=([5-9]|[1-9][0-9]+)\b' /etc/pam.d/common-password | cut -d '=' -f 2 + if($test1 -ge 5){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.4.4" + Task = "Ensure password hashing algorithm is SHA-512" + Test = { + $test1 = grep -E '^\s*password\s+(\[success=1\s+default=ignore\]|required)\s+pam_unix\.so\s+([^#]+\s+)?sha512\b' /etc/pam.d/common-password + if($test1 -match "password" -and $test1 -match "success=1" -and $test1 -match "default=ignore" -and $test1 -match "sha512"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.1.1" + Task = "Ensure minimum days between password changes is configured" + Test = { + $test1 = grep PASS_MIN_DAYS /etc/login.defs | cut -d ' ' -f 2 + $test2 = awk -F : '(/^[^:]+:[^!*]/ && $4 < 1){print $1 " " $4}' /etc/shadow + if($test1 -ge 1 -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.1.2" + Task = "Ensure password expiration is 365 days or less" + Test = { + try{ + $res=grep PASS_MAX_DAYS /etc/login.defs | tail -1 | cut -d ' ' -f 1 + $res=$res.substring($res.Length -3) + + $min=grep PASS_MIN_DAYS /etc/login.defs | tail -1 | cut -d ' ' -f 2 + $min=$min.substring($min.Length -1) + + $test1 = awk -F: '(/^[^:]+:[^!*]/ && ($5>365 || $5~/([0-1]|-1|\s*)/)){print $1 " " $5}' /etc/shadow + if($res -le 365 -and $res -gt $min -and $test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "5.5.1.3" + Task = "Ensure password expiration warning days is 7 or more" + Test = { + $test1 = grep PASS_WARN_AGE /etc/login.defs | cut -d ' ' -f 2 + $test2 = bash -c "awk -F: '(/^[^:]+:[^!*]/ && `$6<7){print `$1 " " `$6}' /etc/shadow" + if($test1 -ge 7 -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.1.4" + Task = "Ensure inactive password lock is 30 days or less" + Test = { + $test1 = useradd -D | grep INACTIVE | cut -d '=' -2 + if($test1 -le 30){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.1.5" + Task = "Ensure all users last password change date is in the past" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-5.5.1.5.sh" + $result=bash $path + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.2" + Task = "Ensure system accounts are secured" + Test = { + $test1 = awk -F: '$1!~/(root|sync|shutdown|halt|^\+)/ && $3<'"$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)"' && $7!~/((\/usr)?\/sbin\/nologin)/ && $7!~/(\/bin)?\/false/ {print}' /etc/passwd + $test2 = awk -F: '($1!~/(root|^\+)/ && $3<'"$(awk '/^\s*UID_MIN/{print $2}'/etc/login.defs)"') {print $1}' /etc/passwd | xargs -I '{}' passwd -S '{}' | awk '($2!~/LK?/) {print $1}' + if($test1 -eq $null -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.5.3" + Task = "Ensure default group for the root account is GID 0" + Test = { + $test1 = grep "^root:" /etc/passwd | cut -f4 -d ':' + if($test1 -eq 0){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "5.7" + Task = "Ensure access to the su command is restricted" + Test = { + $test1 = grep pam_wheel.so /etc/pam.d/su + + if($test1 -match "^\s*auth\s+required\s+pam_wheel.so\s+use_uid\s+group="){ + $test2 = $test1 | cut -d '=' -f 2 + $test3 = grep $test2 /etc/group | cut -d ':' -f 4 + if($test3 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.1" + Task = "Audit system file permissions" + Test = { + $test1 = dpkg --verify $(dpkg --get-selections | awk '{print $1}') + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.2" + Task = "Ensure permissions on /etc/passwd are configured" + Test = { + $test1 = stat /etc/passwd + if($test1 -eq "Access: (0644/-rw-r--r--)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.3" + Task = "Ensure permissions on /etc/passwd- are configured" + Test = { + $test1 = stat /etc/passwd- + if($test1 -eq "Access: (0644/-rw-r--r--)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.4" + Task = "Ensure permissions on /etc/group are configured" + Test = { + $test1 = stat /etc/group + if($test1 -eq "Access: (0644/-rw-r--r--)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.5" + Task = "Ensure permissions on /etc/group- are configured" + Test = { + $test1 = stat /etc/group- | grep 0644 + if($test1 -eq "Access: (0644/-rw-r--r--)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.6" + Task = "Ensure permissions on /etc/shadow are configured" + Test = { + $test1 = stat /etc/shadow | grep 0640 + if($test1 -eq "Access: (0640/-rw-r-----)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+0/\s+root)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.7" + Task = "Ensure permissions on /etc/shadow- are configured" + Test = { + $test1 = stat /etc/shadow- | grep 0640 + if($test1 -eq "Access: (0640/-rw-r-----)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+42/\s+shadow)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.8" + Task = "Ensure permissions on /etc/gshadow are configured" + Test = { + $test1 = stat /etc/gshadow | grep 0640 + if($test1 -eq "Access: (0640/-rw-r-----)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+42/\s+shadow)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.9" + Task = "Ensure permissions on /etc/gshadow- are configured" + Test = { + $test1 = stat /etc/gshadow- | grep 0640 + if($test1 -eq "Access: (0640/-rw-r-----)\s+Uid: (\s+0/\s+root)\s+Gid: (\s+42/\s+shadow)"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.10" + Task = "Ensure no world writable files exist" + Test = { + #$partitions = mapfile -t partitions < (sudo fdisk -l | grep -o '/dev/[^ ]*') + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -0002 + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.11" + Task = "Ensure no unowned files or directories exist" + Test = { + try{ + $test1 = df --local -P | awk "{if (NR -ne 1) { print `$6 }}" | xargs -I '{}' find '{}' -xdev -nouser + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "6.1.12" + Task = "Ensure no ungrouped files or directories exist" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nogroup + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.1.13" + Task = "Audit SUID executables" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -4000 + $message = "" + foreach($line in $test1){ + $message += "
$line" + } + return @{ + Message = "Please review following list of files: $($message)" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "6.1.14" + Task = "Audit SGID executables" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -2000 + $message = "" + foreach($line in $test1){ + $message += "
$line" + } + return @{ + Message = "Please review following list of files: $($message)" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "6.2.1" + Task = "Ensure accounts in /etc/passwd use shadowed passwords" + Test = { + $test1 = awk -F: '($2 != "x" ) { print $1 " is not set to shadowed passwords "}'/etc/passwd + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.2" + Task = "Ensure password fields are not empty" + Test = { + $test1 = awk -F: '($2 == "" ) { print $1 " does not have a password "}' /etc/shadow + if($test1 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.3" + Task = "Ensure all groups in /etc/passwd exist in /etc/group" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.3.sh" + $result=bash $path + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.4" + Task = "Ensure all users' home directories exist" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.4.sh" + $result=bash $path + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +# [AuditTest] @{ +# Id = "6.2.5" +# Task = "Ensure users own their home directories" +# Test = { +# Write-Error "Test" +# $parentPath = Split-Path -Parent -Path $PSScriptRoot +# $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.5.sh" +# $result=bash $path +# Write-Error "Test" +# if($result -eq $null){ +# return @{ +# Message = "Compliant" +# Status = "True" +# } +# } +# return @{ +# Message = "Not-Compliant" +# Status = "False" +# } +# } +# } +[AuditTest] @{ + Id = "6.2.6" + Task = "Ensure users' home directories permissions are 750 or more restrictive" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.6.sh" + $result=bash $path + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.7" + Task = "Ensure users' dot files are not group or world writable" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.7.sh" + $result=bash $path + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.8" + Task = "Ensure no users have .netrc files" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.8.sh" + $result=bash $path + if($result -match "FAILED"){ + return @{ + Message = "Not-Compliant. Permissions need to get updated." + Status = "False" + } + } + if($result -match "WARNING" -and $result -notmatch "FAILED"){ + return @{ + Message = "Some changed should be made." + Status = "Warning" + } + } + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.9" + Task = "Ensure no users have .forward files" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.9.sh" + $result=bash $path + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.10" + Task = "Ensure no users have .rhosts files" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.10.sh" + $result=bash $path + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.11" + Task = "Ensure root is the only UID 0 account" + Test = { + $test1 = awk -F: '($3 == 0) { print $1 }' /etc/passwd + if($test1 -match "root"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.12" + Task = "Ensure root PATH Integrity" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.12.sh" + $result=bash $path + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.13" + Task = "Ensure no duplicate UIDs exist" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.13.sh" + $result=bash $path + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.14" + Task = "Ensure no duplicate GIDs exist" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.14.sh" + $result=bash $path + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.15" + Task = "Ensure no duplicate user names exist" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.15.sh" + $result=bash $path + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.16" + Task = "Ensure no duplicate group names exist" + Test = { + $parentPath = Split-Path -Parent -Path $PSScriptRoot + $path = $parentPath+"/Helpers/ShellScripts/CIS-Ubuntu-6.2.16.sh" + $result=bash $path + if($result -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.17" + Task = "Ensure shadow group is empty" + Test = { + $test1 = awk -F: '($1=="shadow") {print $NF}' /etc/group + $test2 = awk -F: -v GID="$(awk -F: '($1=="shadow") {print $3}' /etc/group)" '($4==GID) {print $1}' /etc/passwd + if($test1.Length -eq 0 -and $test2 -eq $null){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} \ No newline at end of file diff --git a/ATAPAuditor/AuditGroups/Ubuntu Linux 22.04-CIS-2.0.0.ps1 b/ATAPAuditor/AuditGroups/Ubuntu Linux 22.04-CIS-2.0.0.ps1 new file mode 100644 index 0000000..a150f34 --- /dev/null +++ b/ATAPAuditor/AuditGroups/Ubuntu Linux 22.04-CIS-2.0.0.ps1 @@ -0,0 +1,4109 @@ +. "$RootPath\Helpers\LinuxHelper.ps1" + +$rcFirewallStatus1 = "Using nftables" +$rcFirewallStatus2 = "Using ufw" +$rcFirewallStatus3 = "Using iptables" + +$retCompliant = @{ + Message = $rcCompliant + Status = $rcTrue +} +$retNonCompliant = @{ + Message = $rcNonCompliant + Status = $rcFalse +} +$retCompliantIPv6Disabled = @{ + Message = $rcCompliantIPv6isDisabled + Status = $rcTrue +} +$retNonCompliantManualReviewRequired = @{ + Message = $rcNonCompliantManualReviewRequired + Status = $rcNone +} +$retUsingFW1 = @{ + Message = $rcFirewallStatus1 + Status = $rcNone +} +$retUsingFW2 = @{ + Message = $rcFirewallStatus2 + Status = $rcNone +} +$retUsingFW3 = @{ + Message = $rcFirewallStatus3 + Status = $rcNone +} + +# Firewall evaluation +function GetFirewallStatus { + # 0 - undefined + # 1 - using nftables + # 2 - using ufw + # 3 - using iptables + + $t_UFW = Test-PackageInstalled -PackageName ufw + $t_NFT = Test-PackageInstalled -PackageName nftables + $t_IPT = Test-PackageInstalled -PackageName iptables + $t_UFW_en = systemctl is-enabled ufw 2>/dev/null + if ($t_UFW){ + $t_UFW_inac = ufw status 2>/dev/null | grep -iE "Status: Ina[ck]tive?" + $t_UFW_ac = ufw status 2>/dev/null | grep -iE "Status: A[ck]tive?" + } else { + $t_UFW_ac = $null + $t_UFW_inac = $null + } + $t_NFT_en = systemctl is-enabled nftables.service 2>/dev/null + + # Testing 1 - nftable installed, ufw not or inactive + if ($t_NFT -and ! $t_IPT -and (! $t_UFW -or $t_UFW_inac -ne $null) -and $t_NFT_en -match "enabled"){ + return 1 + } + + # Testing 2 - ufw, iptables installed, nftables not + if ( $t_UFW -and $t_UFW_ac -ne $null -and $t_UFW_en -match "enabled" -and $t_IPT -and ! $t_NFT){ + return 2 + } + + # Testing 3 - only iptables + if (! $t_NFT -and ! $t_UFW -and $t_IPT){ + return 3 + } + + return 0 +} + +$FirewallStatus = GetFirewallStatus + +$parentPath = Split-Path -Parent -Path $PSScriptRoot +$scriptPath = $parentPath + "/Helpers/ShellScripts/Ubuntu22.04_Debian12/" +$commonPath = $parentPath + "/Helpers/ShellScripts/common/" + +[AuditTest] @{ + Id = "1.1.1.1" + Task = "Ensure cramfs kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.2" + Task = "Ensure freevxfs kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.3" + Task = "Ensure hfs kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.4" + Task = "Ensure hfsplus kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.5" + Task = "Ensure jffs2 kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.6" + Task = "Ensure squashfs kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.7" + Task = "Ensure udf kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.1.8" + Task = "Ensure usb-storage kernel module is not available" + Test = { + $script = $commonPath + "1.1.1.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.1.1" + Task = "Ensure /tmp is a separate partition" + Test = { + $result = findmnt --kernel /tmp + if($result -match "/tmp"){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.1.2.1.2" + Task = "Ensure nodev option set on /tmp partition" + Test = { + $script = $commonPath + "1.1.2.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.1.3" + Task = "Ensure nosuid option set on /tmp partition" + Test = { + $script = $commonPath + "1.1.2.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.1.4" + Task = "Ensure noexec option set on /tmp partition" + Test = { + $result = findmnt --kernel /tmp | grep noexec + if($result -match "noexec"){ + return $retCompliant + } + + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "1.1.2.2.1" + Task = "Ensure /dev/shm is a separate partition" + Test = { + $script = $scriptPath + "1.1.2.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + +[AuditTest] @{ + Id = "1.1.2.2.2" + Task = "Ensure nodev option set on /dev/shm partition" + Test = { + $script = $commonPath + "1.1.2.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.2.3" + Task = "Ensure nosuid option set on /dev/shm partition" + Test = { + $script = $commonPath + "1.1.2.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.2.4" + Task = "Ensure noexec option set on /dev/shm partition" + Test = { + $script = $commonPath + "1.1.2.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.3.1" + Task = "Ensure separate partition exists for /home" + Test = { + $result = findmnt --kernel /home + if($result -match "/home"){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.1.2.3.2" + Task = "Ensure nodev option set on /home partition" + Test = { + $script = $commonPath + "1.1.2.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.3.3" + Task = "Ensure nosuid option set on /home partition" + Test = { + $script = $commonPath + "1.1.2.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.4.1" + Task = "Ensure separate partition exists for /var" + Test = { + $result = findmnt --kernel /var + if($result -match !$null){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.1.2.4.2" + Task = "Ensure nodev option set on /var partition" + Test = { + $script = $commonPath + "1.1.2.4.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.4.3" + Task = "Ensure nosuid option set on /var partition" + Test = { + $script = $commonPath + "1.1.2.4.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.5.1" + Task = "Ensure separate partition exists for /var/tmp" + Test = { + $result = findmnt --kernel /var/tmp + if($result -match "/var/tmp"){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.1.2.5.2" + Task = "Ensure nodev option set on /var/tmp partition" + Test = { + $script = $commonPath + "1.1.2.5.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.5.3" + Task = "Ensure nosuid option set on /var/tmp partition" + Test = { + $script = $commonPath + "1.1.2.5.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.5.4" + Task = "Ensure noexec option set on /var/tmp partition" + Test = { + $script = $commonPath + "1.1.2.5.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.6.1" + Task = "Ensure separate partition exists for /var/log" + Test = { + $result = findmnt --kernel /var/log + if($result -match !$null){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.1.2.6.2" + Task = "Ensure nodev option set on /var/log partition" + Test = { + $script = $commonPath + "1.1.2.6.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.6.3" + Task = "Ensure nosuid option set on /var/log partition" + Test = { + $script = $commonPath + "1.1.2.6.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.6.4" + Task = "Ensure noexec option set on /var/log partition" + Test = { + $script = $commonPath + "1.1.2.6.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.7.1" + Task = "Ensure separate partition exists for /var/log/audit" + Test = { + $result = findmnt --kernel /var/log/audit + if($result -match "/var/log/audit"){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.1.2.7.2" + Task = "Ensure nodev option set on /var/log/audit partition" + Test = { + $script = $commonPath + "1.1.2.7.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.7.3" + Task = "Ensure nosuid option set on /var/log/audit partition" + Test = { + $script = $commonPath + "1.1.2.7.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.1.2.7.4" + Task = "Ensure noexec option set on /var/log/audit partition" + Test = { + $script = $commonPath + "1.1.2.7.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.2.1.1" + Task = "Ensure GPG keys are configured" + Test = { + $result = apt-key list + if($result -ne $null){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.2.1.2" + Task = "Ensure package manager repositories are configured" + Test = { + $result = apt-cache policy + if($result -ne $null){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.2.2.1" + Task = "Ensure updates, patches, and additional security software are installed" + Test = { + $output = apt -s upgrade + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.3.1.1" + Task = "Ensure AppArmor is installed" + Test = { + $result = Test-PackageInstalled -PackageName apparmor 2>/dev/null + if($result){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.3.1.2" + Task = "Ensure AppArmor is enabled in the bootloader configuration" + Test = { + $script = $scriptPath + "1.3.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.3.1.3" + Task = "Ensure all AppArmor Profiles are in enforce or complain mode" + Test = { + $profileMode1 = apparmor_status | grep profiles | sed '1!d' | cut -d ' ' -f 1 + $profileMode2 = apparmor_status | grep profiles | sed '2!d' | cut -d ' ' -f 1 + $profileMode3 = apparmor_status | grep profiles | sed '3!d' | cut -d ' ' -f 1 + $result = expr $profileMode3 + $profileMode2 + + $unconfinedProcesses = apparmor_status | grep processes | sed '4!d' | cut -d ' ' -f 1 + + if($result -eq $profileMode1 -and $unconfinedProcesses -eq 0){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.3.1.4" + Task = "Ensure all AppArmor Profiles are enforcing" + Test = { + $script = $scriptPath + "1.3.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.4.1" + Task = "Ensure bootloader password is set" + Test = { + $result1 = grep "^set superusers" /boot/grub/grub.cfg + $result2 = grep "^password" /boot/grub/grub.cfg + if($result1 -match "set superusers=" -and $result2 -match "password_pbkdf2"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.4.2" + Task = "Ensure access to bootloader config is configured" + Test = { + $script = $commonPath + "1.4.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.5.1" + Task = "Ensure address space layout randomization is enabled" + Test = { + $script = $commonPath + "1.5.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.5.2" + Task = "Ensure ptrace_scope is restricted" + Test = { + $script = $commonPath + "1.5.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} + + +[AuditTest] @{ + Id = "1.5.3" + Task = "Ensure core dumps are restricted" + Test = { + $script = $scriptPath + "1.5.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.5.4" + Task = "Ensure prelink is not installed" + Test = { + $test = Test-PackageInstalled -PackageName prelink + if(! $test){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "1.5.5" + Task = "Ensure Automatic Error Reporting is not enabled" + Test = { + $result1 = dpkg-query -s apport > /dev/null 2>&1 && grep -Psi -- '^\h*enabled\h*=\h*[^0]\b' /etc/default/apport + $result2 = systemctl is-active apport.service | grep '^active' + if($result1 -eq $null -and $result2 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.6.1" + Task = "Ensure message of the day is configured properly" + Test = { + $script = $scriptPath + "1.6.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.6.2" + Task = "Ensure local login warning banner is configured properly" + Test = { + $output1 = cat /etc/issue + + if($output1 -eq $null){ + return $retCompliant + } + + $output2 = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue + + if($output1 -ne $null -and $output2 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.6.3" + Task = "Ensure remote login warning banner is configured properly" + Test = { + $output1 = cat /etc/issue.net + + if($output1 -eq $null){ + return $retCompliant + } + + $output2 = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue.net + + if($output1 -ne $null -and $output2 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.6.4" + Task = "Ensure access to /etc/motd is configured" + Test = { + $script = $scriptPath + "1.6.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "1.6.5" + Task = "Ensure access to /etc/issue is configured" + Test = { + $output = stat -c '%#a' /etc/issue | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.6.6" + Task = "Ensure access to /etc/issue.net is configured" + Test = { + $output = stat -c '%#a' /etc/issue.net | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.1" + Task = "Ensure GDM is removed" + Test = { + $test = Test-PackageInstalled -PackageName gdm3 + if(! $test){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.2" + Task = "Ensure GDM login banner is configured" + Test = { + $path = $scriptPath + "1.8.2.sh" + $result = bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.3" + Task = "Ensure GDM disable-user-list option is enabled" + Test = { + $path = $scriptPath + "1.8.3.sh" + $result = bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.4" + Task = "Ensure GDM screen locks when the user is idle" + Test = { + $path = $scriptPath + "1.8.4.sh" + $result = bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.5" + Task = "Ensure GDM screen locks cannot be overridden" + Test = { + $path = $scriptPath + "1.8.5.sh" + $result = bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.6" + Task = "Ensure GDM automatic mounting of removable media is disabled" + Test = { + $path = $scriptPath + "1.8.6.sh" + $result = bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.7" + Task = "Ensure GDM disabling automatic mounting of removable media is not overridden" + Test = { + $path = $scriptPath + "1.8.7.sh" + $result = bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.8" + Task = "Ensure GDM autorun-never is enabled" + Test = { + $path = $scriptPath + "1.8.8.sh" + $result = bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.9" + Task = "Ensure GDM autorun-never is not overridden" + Test = { + $path = $scriptPath + "1.8.9.sh" + $result = bash $path + if($?){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "1.7.10" + Task = "Ensure XDCMP is not enabled" + Test = { + $script = $scriptPath + "1.7.10.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "2.1.1" + Task = "Ensure autofs services are not in use" + Test = { + $test = Test-PackageInstalled -PackageName autofs + if(! $test){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null autofs.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.2" + Task = "Ensure avahi daemon services are not in use" + Test = { + $status = Test-PackageInstalled -PackageName avahi-daemon + if(! $status){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null avahi-daemon.socket + if(! $?){ + $test3 = systemctl is-enabled 2>/dev/null avahi-daemon.service + if(! $?){ + return $retCompliant + } + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.3" + Task = "Ensure dhcp server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName isc-dhcp-server + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null isc-dhcp-server.service + if(! $?){ + $test2 = systemctl is-enabled 2>/dev/null isc-dhcp-server6.service + if(! $?){ + return $retCompliant + } + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.4" + Task = "Ensure dns server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName bind9 + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null bind9.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.5" + Task = "Ensure dnsmasq server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName dnsmasq + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null dnsmasq.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.6" + Task = "Ensure ftp server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName vsftpd + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null vsftpd.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.7" + Task = "Ensure ldap server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName slapd + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null slapd.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.8" + Task = "Ensure message access server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName dovecot-imapd + $test2 = Test-PackageInstalled -PackageName dovecot-pop3d + if(! $test1 -and ! $test2){ + return $retCompliant + } + else{ + $test3 = systemctl is-enabled 2>/dev/null dovecot.socket + if(! $?){ + $test4 = systemctl is-enabled 2>/dev/null dovecot.service + if(! $?){ + return $retCompliant + } + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.9" + Task = "Ensure network file system services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName nfs-kernel-server + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null nfs-kernel.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.10" + Task = "Ensure nis server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName ypserv + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null ypserv.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.11" + Task = "Ensure print server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName cups + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null cups.service + if(! $?){ + $test3 = systemctl is-enabled 2>/dev/null cups.socket + if(! $?){ + return $retCompliant + } + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.12" + Task = "Ensure rpcbind services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName rpcbind + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null rpcbind.service + if(! $?){ + $test3 = systemctl is-enabled 2>/dev/null rpcbind.socket + if(! $?){ + return $retCompliant + } + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.13" + Task = "Ensure rsync services are not in use" + Test = { + $script = $commonPath + "2.1.13.sh" + bash $script + if ($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.14" + Task = "Ensure samba file server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName samba 2>/dev/null + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null samba.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.15" + Task = "Ensure snmp services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName snmpd + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null snmpd.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.16" + Task = "Ensure tftp server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName tftpd-hpa + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null tftpd-hpa.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.17" + Task = "Ensure web proxy server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName squid + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null squid.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.18" + Task = "Ensure web server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName apache2 + $test2 = Test-PackageInstalled -PackageName ginx + if(! $test1 -and ! $test2){ + return $retCompliant + } + else{ + $services = 'apache2.service', 'apache2.socket', 'nginx.service', 'nginx.socket' + $test3 = "disabled" + foreach ($service in $services){ + $test4 = systemctl is-enabled $service 2>/dev/null + if($?){ + $test3 = "enabled" + } + } + if($test3 -match "disabled"){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.19" + Task = "Ensure xinetd services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName xinetd + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null xinetd.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.20" + Task = "Ensure X window server services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName xserver-common + if(! $test1){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.21" + Task = "Ensure mail transfer agent is configured for local-only mode" + Test = { + $test1 = ss -lntu | grep -E ':25\s' | grep -E -v '\s(127.0.0.1|::1):25\s' + if($test1 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.1.22" + Task = "Ensure only approved services are listening on a network interface" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "2.2.1" + Task = "Ensure NIS Client is not installed" + Test = { + $test1 = Test-PackageInstalled -PackageName nis + if(! $test1){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.2.2" + Task = "Ensure rsh client is not installed" + Test = { + $status = Test-PackageInstalled -PackageName rsh-client + if(! $status){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.2.3" + Task = "Ensure talk client is not installed" + Test = { + $test1 = Test-PackageInstalled -PackageName talk + if(! $test1){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.2.4" + Task = "Ensure telnet client Server is not installed" + Test = { + $test1 = Test-PackageInstalled -PackageName telnet + if(! $test1){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.2.5" + Task = "Ensure ldap client is not installed" + Test = { + $test1 = Test-PackageInstalled -PackageName lapd-utils + if(! $test1){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.2.6" + Task = "Ensure ftp client is not installed" + Test = { + $test1 = Test-PackageInstalled -PackageName ftp + if(! $test1){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "2.3.1.1" + Task = "Ensure a single time synchronization daemon is in use" + Test = { + $path = $scriptPath + "2.1.1.1.sh" + $result = bash $path + if($result -match "PASS:"){ + return $retCompliant + } + + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.3.2.1" + Task = "Ensure systemd-timesyncd configured with authorized timeserver" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "2.3.2.2" + Task = "Ensure systemd-timesyncd is enabled and running" + Test = { + $test1 = systemctl is-enabled systemd-timesyncd.service + $time = timedatectl status + if($test1 -match "enabled" -and $time -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.3.3.1" + Task = "Ensure chrony is configured with authorized timeserver" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "2.3.3.2" + Task = "Ensure chrony is running as user _chrony" + Test = { + $script = $scriptPath + "2.3.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "2.3.3.3" + Task = "Ensure chrony is enabled and running" + Test = { + $test1 = $(systemctl is-enabled cron.service 1>/dev/null 2>/dev/null; echo $?) + $test2 = $(systemctl is-active cron.service 1>/dev/null 2>/dev/null; echo $?) + if($test1 -and $test2 ){ + return $retCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.1" + Task = "Ensure cron daemon is enabled and active" + Test = { + $test1 = systemctl is-enabled cron + $test2 = systemctl status cron | grep 'Active: active (running) ' + if($test1 -eq "enabled" -and $test2 -match "running"){ + return $retCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.2" + Task = "Ensure permissions on /etc/crontab are configured" + Test = { + $test1 = stat -c '%#a' /etc/crontab | grep -q "0600" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.3" + Task = "Ensure permissions on /etc/cron.hourly are configured" + Test = { + $test1 = stat -c '%#a' /etc/cron.hourly/ | grep -q 0700 + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.4" + Task = "Ensure permissions on /etc/cron.daily are configured" + Test = { + $test1 = stat -c '%#a' /etc/cron.daily/ | grep -q "0700" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.5" + Task = "Ensure permissions on /etc/cron.weekly are configured" + Test = { + $test1 = stat -c '%#a' /etc/cron.weekly/ | grep -q "0700" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.6" + Task = "Ensure permissions on /etc/cron.monthly are configured" + Test = { + $test1 = stat -c '%#a' /etc/cron.monthly/ | grep -q "0700" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.7" + Task = "Ensure permissions on /etc/cron.d are configured" + Test = { + $test1 = stat -c '%#a' /etc/cron.d/ | grep -q "0700" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "2.4.1.8" + Task = "Ensure crontab is restricted to authorized users" + Test = { + $script = $commonPath + "2.4.1.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "2.4.2.1" + Task = "Ensure at is restricted to authorized users" + Test = { + $script = $commonPath + "2.4.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.1.1" + Task = "Ensure IPv6 status is identified" + Test = { + $path = $scriptPath + "3.1.1.sh" + $result = bash $path + if($result -match "IPv6 is enabled on the system"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "3.1.2" + Task = "Ensure wireless interfaces are disabled" + Test = { + $script = $commonPath + "3.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.1.3" + Task = "Ensure bluetooth services are not in use" + Test = { + $test1 = Test-PackageInstalled -PackageName bluez + if(! $test1){ + return $retCompliant + } + else{ + $test2 = systemctl is-enabled 2>/dev/null bluetooth.service + if(! $?){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "3.2.1" + Task = "Ensure dccp kernel module is not available" + Test = { + $script = $commonPath + "3.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.2.2" + Task = "Ensure tipc kernel module is not available" + Test = { + $script = $commonPath + "3.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.2.3" + Task = "Ensure rds kernel module is not available" + Test = { + $script = $commonPath + "3.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.2.4" + Task = "Ensure sctp kernel module is not available" + Test = { + $script = $commonPath + "3.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.1" + Task = "Ensure ip forwarding is disabled" + Test = { + $script = $commonPath + "3.3.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.2" + Task = "Ensure packet redirect sending is disabled" + Test = { + $script = $commonPath + "3.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.3" + Task = "Ensure bogus icmp responses are ignored" + Test = { + $script = $commonPath + "3.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.4" + Task = "Ensure broadcast icmp requests are ignored" + Test = { + $script = $commonPath + "3.3.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.5" + Task = "Ensure icmp redirects are not accepted" + Test = { + $script = $commonPath + "3.3.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.6" + Task = "Ensure secure icmp redirects are not accepted" + Test = { + $script = $commonPath + "3.3.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.7" + Task = "Ensure reverse path filtering is enabled" + Test = { + $script = $commonPath + "3.3.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.8" + Task = "Ensure source routed packets are not accepted" + Test = { + $script = $commonPath + "3.3.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.9" + Task = "Ensure suspicious packets are logged" + Test = { + $script = $commonPath + "3.3.9.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.10" + Task = "Ensure tcp syn cookies is enabled" + Test = { + $script = $commonPath + "3.3.10.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "3.3.11" + Task = "Ensure ipv6 router advertisements are not accepted" + Test = { + $script = $commonPath + "3.3.11.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "4.1.1" + Task = "Ensure ufw is installed" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = Test-PackageInstalled -PackageName ufw + if($test1){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.1.2" + Task = "Ensure iptables-persistent is not installed with ufw" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = Test-PackageInstalled -PackageName iptables-persistent + if(! $test1){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.1.3" + Task = "Ensure ufw service is enabled" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = systemctl is-enabled ufw 2>/dev/null + $test2 = systemctl is-active ufw 2>/dev/null + if($test1 -match "enabled" -and $test2 -match "active"){ + $test3 = ufw status | grep -iE "Status: A[ck]tive?" + if($test3 -ne $null){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.1.4" + Task = "Ensure ufw loopback traffic is configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = Test-PackageInstalled -PackageName ufw + if($test1){ + $test2 = ufw status verbose | grep -iE "Status: A[ck]tive?" + if($test2 -eq $null){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.1.5" + Task = "Ensure ufw outbound connections are configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = Test-PackageInstalled -PackageName ufw + if($test1){ + $test2 = ufw status numbered | grep -iE "Status: Ina[ck]tive?" + if($test2 -eq $null){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.1.6" + Task = "Ensure ufw firewall rules exist for all open ports" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $path = $scriptPath + "3.5.1.6.sh" + $result = bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.1.7" + Task = "Ensure ufw default deny firewall policy" + Test = { + $test1 = Test-PackageInstalled -PackageName ufw + if($test1){ + $test2 = ufw status verbose | grep -iE "allow" + if($test2 -eq $null){ + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.2.1" + Task = "Ensure nftables is installed" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = Test-PackageInstalled -PackageName nftables + if($test1){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.2.2" + Task = "Ensure ufw is uninstalled or disabled with nftables" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = Test-PackageInstalled -PackageName ufw + if(! $test1){ + return $retCompliant + } else { + $test2 = ufw status | grep -iE "Status: Ina[ck]tive?" + if($test2 -ne $null) { + return $retCompliant + } + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "4.2.3" + Task = "Ensure iptables are flushed with nftables" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $script = $scriptPath + "4.2.3.sh" + $result = bash $script + if ($?) { + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.2.4" + Task = "Ensure a nftables table exists" + Test = { + try{ + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = nft list tables + if($test1 -match "table"){ + return $retCompliant + } + return $retNonCompliant + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.2.5" + Task = "Ensure nftables base chains exist" + Test = { + try{ + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = nft list ruleset | grep 'hook input' + $test2 = nft list ruleset | grep 'hook forward' + $test3 = nft list ruleset | grep 'hook output' + if($test1 -match "type filter hook input" -and $test2 -match "type filter hook forward" -and $test3 -match "type filter hook output"){ + return $retCompliant + } + return $retNonCompliant + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.2.6" + Task = "Ensure nftables loopback traffic is configured" + Test = { + try{ + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + if($isIPv6Disabled -ne $true){ + $test1 = nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept' + $test2 = nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr' + if($test1 -match 'iif "lo" accept' -and $test2 -match "ip saddr 127.0.0.0/8 counter packets 0 bytes 0 drop"){ + return $retCompliant + } + } + else{ + $test = nft list ruleset | awk '/hook input/,/}/' | grep 'ip6 saddr' + if($test -match 'ip6 saddr ::1 counter packets 0 bytes 0 drop'){ + return $retCompliant + } + } + return $retNonCompliant + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.2.7" + Task = "Ensure nftables outbound and established connections are configured" + Test = { + try{ + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = nft list ruleset | awk '/hook input/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + $test2 = nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + if($test1 -match "ip protocol tcp ct state established accept" -and $test1 -match "p protocol udp ct state established accept" -and $test1 -match "ip protocol icmp ct state established accept" -and $test2 -match "ip protocol tcp ct state established,related,new accep" -and $test2 -match "ip protocol udp ct state established,related,new accept" -and $test2 -match "ip protocol icmp ct state established,related,new accept"){ + return $retCompliant + } + return $retNonCompliant + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.2.8" + Task = "Ensure nftables default deny firewall policy" + Test = { + try{ + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = nft list ruleset | grep 'hook input' + $test2 = nft list ruleset | grep 'hook forward' + $test3 = nft list ruleset | grep 'hook output' + if($test1 -match "policy drop" -and $test2 -match "policy drop" -and $test3 -match "policy drop"){ + return $retCompliant + } + return $retNonCompliant + } + catch{ + return @{ + Message = "Command not found!" + Status = "False" + } + } + } +} +[AuditTest] @{ + Id = "4.2.9" + Task = "Ensure nftables service is enabled" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $test1 = systemctl is-enabled nftables + if($test1 -match "enabled"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.2.10" + Task = "Ensure nftables rules are permanent" + Test = { + if ($FirewallStatus -match 2) { + return $retUsingFW1 + } + if ($FirewallStatus -match 3) { + return $retUsingFW3 + } + $path1 = $scriptPath + "3.5.2.10_1.sh" + $path2 = $scriptPath + "3.5.2.10_2.sh" + $path3 = $scriptPath + "3.5.2.10_3.sh" + if($path1 -ne $null -and $path2 -ne $null -and $path3 -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.3.1.1" + Task = "Ensure iptables packages are installed" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $test1 = Test-PackageInstalled -PackageName iptables-persistent + if($test1){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.3.1.2" + Task = "Ensure nftables is not installed with iptables" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $test1 = Test-PackageInstalled -PackageName nftables + if(! $test1){ + return $retNonCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "4.3.1.3" + Task = "Ensure ufw is uninstalled or disabled with iptables" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $test1 = Test-PackageInstalled -PackageName ufw + if(! $test1){ + return $retCompliant + } else { + $test2 = ufw status | grep -iE "Status: Ina[ck]tive?" + $test3 = systemctl is-enabled ufw + if($test2 -ne $null -and $test3 -match "masked") { + return $retCompliant + } + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.3.2.1" + Task = "Ensure iptables default deny firewall policy" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $output = iptables -L + $test1 = $output -match "DROP" | grep "Chain INPUT (policy DROP)" + $test2 = $output -match "DROP" | grep "Chain FORWARD (policy DROP)" + $test3 = $output -match "DROP" | grep "Chain OUTPUT (policy DROP)" + if($test1 -ne $null -and $test2 -ne $null -and $test3 -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.3.2.2" + Task = "Ensure iptables loopback traffic is configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $test1 = iptables -L INPUT -v -n | grep "Chain\s*INPUT\s*(policy\s*DROP" + $test2 = iptables -L OUTPUT -v -n | grep "Chain\s*OUTPUT\s*(policy\s*DROP" + if($test1 -ne $null -and $test2 -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.3.2.3" + Task = "Ensure iptables outbound and established connections are configured" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $test1 = iptables -L -v -n + if($test1 -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} +# 3.5.3.2.4 ... + +[AuditTest] @{ # in CIS it's automated, but in Excelsheet it's manual + Id = "4.3.2.4" + Task = "Ensure iptables firewall rules exist for all open ports" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "4.3.3.1" + Task = "Ensure ip6tables default deny firewall policy" + Test = { + if ($FirewallStatus -match 1) { + return $retUsingFW1 + } + if ($FirewallStatus -match 2) { + return $retUsingFW3 + } + $output = ip6tables -L + $test11 = $output -match "DROP" | grep "Chain INPUT (policy DROP)" + $test12 = $output -match "REJECT" | grep "Chain INPUT (policy REJECT)" + $test21 = $output -match "DROP" | grep "Chain OUTPUT (policy DROP)" + $test22 = $output -match "REJECT" | grep "Chain OUTPUT (policy REJECT)" + $test31 = $output -match "DROP" | grep "Chain FORWARD (policy DROP)" + $test32 = $output -match "REJECT" | grep "Chain FORWARD (policy REJECT)" + + if ($IPv6Status -eq $false) { + return @{ + Message = "IPv6 is disabled" + Status = "True" + } + } + if(($test11 -ne $null -or $test12 -ne $null) -and ($test21 -ne $null -or $test22 -ne $null) -and ($test31 -ne $null -or $test32 -ne $null)){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "4.3.3.2" + Task = "Ensure ip6tables loopback traffic is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "4.3.3.3" + Task = "Ensure ip6tables outbound and established connections are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "4.3.3.4" + Task = "Ensure ip6tables firewall rules exist for all open ports" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "5.1.1" + Task = "Ensure cron daemon is enabled and running" + Test = { + $test1 = systemctl is-enabled cron + $test2 = systemctl status cron | grep 'Active: active (running) ' + if($test1 -eq "enabled" -and $test2 -match "running"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.1.2" + Task = "Ensure permissions on /etc/crontab are configured" + Test = { + $test1 = stat -c '%#a' /etc/crontab | grep -q "0600" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.1.3" + Task = "Ensure permissions on SSH public host key files are configured" + Test = { + $script = $commonPath + "5.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.4" + Task = "Ensure sshd access is configured" + Test = { + if (sshd -T | grep -Piq -- "^\h*(allow|deny)(users|groups)\h+\H+") { + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.1.5" + Task = "Ensure sshd Banner is configured" + Test = { + if (sshd -T | grep -Piq -- "^\h*banner\h+\H+") { + return $retCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "5.1.6" + Task = "Ensure sshd Ciphers are configured" + Test = { + $script = $scriptPath + "5.1.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.7" + Task = "Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured" + Test = { + $script = $scriptPath + "5.1.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.8" + Task = "Ensure sshd DisableForwarding is enabled" + Test = { + $script = $scriptPath + "5.1.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.9" + Task = "Ensure sshd GSSAPIAuthentication is disabled" + Test = { + $script = $scriptPath + "5.1.9.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.10" + Task = "Ensure sshd HostbasedAuthentication is disabled" + Test = { + $script = $scriptPath + "5.1.10.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.11" + Task = "Ensure sshd IgnoreRhosts is enabled" + Test = { + $script = $scriptPath + "5.1.11.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.12" + Task = "Ensure sshd KexAlgorithms is configured" + Test = { + $script = $scriptPath + "5.1.12.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.13" + Task = "Ensure sshd LoginGraceTime is configured" + Test = { + $script = $scriptPath + "5.1.13.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.14" + Task = "Ensure sshd LogLevel is configured" + Test = { + $script = $scriptPath + "5.1.14.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.15" + Task = "Ensure sshd MACs are configured" + Test = { + $script = $scriptPath + "5.1.15.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.16" + Task = "Ensure sshd MaxAuthTries is configured" + Test = { + $script = $commonPath + "5.1.16.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.17" + Task = "Ensure sshd MaxSessions is configured" + Test = { + $script = $scriptPath + "5.1.17.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.18" + Task = "Ensure sshd MaxStartups is configured" + Test = { + $script = $scriptPath + "5.1.18.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.19" + Task = "Ensure sshd PermitEmptyPasswords is disabled" + Test = { + $script = $commonPath + "5.1.19.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.20" + Task = "Ensure sshd PermitRootLogin is disabled" + Test = { + $script = $commonPath + "5.1.20.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.21" + Task = "Ensure sshd PermitUserEnvironment is disabled" + Test = { + $script = $commonPath + "5.1.21.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.1.22" + Task = "Ensure sshd UsePAM is enabled" + Test = { + $script = $commonPath + "5.1.22.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.1" + Task = "Ensure sudo is installed" + Test = { + $test1 = Test-PackageInstalled -PackageName sudo + if($test1){ + return $retNonCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "5.2.2" + Task = "Ensure sudo commands use pty" + Test = { + $script = $commonPath + "5.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.3" + Task = "Ensure sudo log file exists" + Test = { + $script = $commonPath + "5.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.4" + Task = "Ensure users must provide password for privilege escalation" + Test = { + $script = $scriptPath + "5.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.5" + Task = "Ensure re-authentication for privilege escalation is not disabled globally" + Test = { + $script = $scriptPath + "5.2.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.6" + Task = "Ensure sudo authentication timeout is configured correctly" + Test = { + $script = $commonPath + "5.2.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.2.7" + Task = "Ensure access to the su command is restricted" + Test = { + $script = $scriptPath + "5.2.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.1.1" + Task = "Ensure latest version of pam is installed" + Test = { + $test1 = Test-PackageInstalled -PackageName libpam-runtime + if($test1){ + return $retNonCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "5.3.1.2" + Task = "Ensure libpam-modules is installed" + Test = { + $test1 = Test-PackageInstalled -PackageName libpam-modules + if($test1){ + return $retNonCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "5.3.1.3" + Task = "Ensure libpam-pwquality is installed" + Test = { + $test1 = Test-PackageInstalled -PackageName libpam-pwquality + if($test1){ + return $retNonCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "5.3.2.1" + Task = "Ensure pam_unix module is enabled" + Test = { + $script = $scriptPath + "5.3.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.2.2" + Task = "Ensure pam_faillock module is enabled" + Test = { + $script = $scriptPath + "5.3.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.2.3" + Task = "Ensure pam_pwquality module is enabled" + Test = { + $script = $scriptPath + "5.3.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.2.4" + Task = "Ensure pam_pwhistory module is enabled" + Test = { + $script = $scriptPath + "5.3.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.1.1" + Task = "Ensure password failed attempts lockout is configured" + Test = { + $script = $commonPath + "5.3.3.1.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.1.2" + Task = "Ensure password unlock time is configured" + Test = { + $script = $commonPath + "5.3.3.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.1.3" + Task = "Ensure password failed attempts lockout includes root account" + Test = { + $script = $commonPath + "5.3.3.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.1" + Task = "Ensure password number of changed characters is configured" + Test = { + $script = $commonPath + "5.3.3.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.2" + Task = "Ensure minimum password length is configured" + Test = { + $script = $commonPath + "5.3.3.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.3" + Task = "Ensure password complexity is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "5.3.3.2.4" + Task = "Ensure password same consecutive characters is configured" + Test = { + $script = $commonPath + "5.3.3.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.5" + Task = "Ensure password maximum sequential characters is configured" + Test = { + $script = $commonPath + "5.3.3.2.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.6" + Task = "Ensure password dictionary check is enabled" + Test = { + $script = $commonPath + "5.3.3.2.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.7" + Task = "Ensure password quality checking is enforced" + Test = { + $script = $scriptPath + "5.3.3.2.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.2.8" + Task = "Ensure password quality is enforced for the root user" + Test = { + $script = $scriptPath + "5.3.3.2.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.3.1" + Task = "Ensure password history remember is configured" + Test = { + $script = $scriptPath + "5.3.3.3.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.3.2" + Task = "Ensure password history is enforced for the root user" + Test = { + $script = $scriptPath + "5.3.3.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.3.3" + Task = "Ensure pam_pwhistory includes use_authtok" + Test = { + $script = $commonPath + "5.3.3.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.4.1" + Task = "Ensure pam_unix does not include nullok" + Test = { + $script = $commonPath + "5.3.3.4.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.4.2" + Task = "Ensure pam_unix does not include remember" + Test = { + $script = $scriptPath + "5.3.3.4.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.4.3" + Task = "Ensure pam_unix includes a strong password hashing algorithm" + Test = { + $script = $scriptPath + "5.3.3.4.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.3.3.4.4" + Task = "Ensure pam_unix includes use_authtok" + Test = { + $script = $commonPath + "5.3.3.4.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.1" + Task = "Ensure password expiration is configured" + Test = { + $script = $commonPath + "5.4.1.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.2" + Task = "Ensure minimum password age is configured" + Test = { + $script = $commonPath + "5.4.1.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.3" + Task = "Ensure password expiration warning days is configured" + Test = { + $script = $commonPath + "5.4.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.4" + Task = "Ensure strong password hashing algorithm is configured" + Test = { + $script = $commonPath + "5.4.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.5" + Task = "Ensure inactive password lock is configured" + Test = { + $script = $commonPath + "5.4.1.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.1.6" + Task = "Ensure all users last password change date is in the past" + Test = { + $path = $scriptPath + "5.5.1.5.sh" + $result = bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.4.2.1" + Task = "Ensure root is the only UID 0 account" + Test = { + $test1 = awk -F: '($3 == 0) { print $1 }' /etc/passwd + if($test1 -match "root"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.4.2.2" + Task = "Ensure root is the only GID 0 account" + Test = { + $test1 = grep "^root:" /etc/passwd | cut -f4 -d ':' + if($test1 -eq 0){ + return $retCompliant + } + return $retNonCompliant + } + } + [AuditTest] @{ + Id = "5.4.2.3" + Task = "Ensure group root is the only GID 0 group" + Test = { + $script = $commonPath + "5.4.2.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.2.4" + Task = "Ensure root password is set" + Test = { + $script = $scriptPath + "5.4.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.2.5" + Task = "Ensure root PATH Integrity" + Test = { + $path = $scriptPath + "6.2.9.sh" + $result = bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.4.2.6" + Task = "Ensure root user umask is configured" + Test = { + $script = $commonPath + "5.4.2.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.2.7" + Task = "Ensure system accounts do not have a valid login shell" + Test = { + $script = $commonPath + "5.4.2.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.2.8" + Task = "Ensure accounts without a valid login shell are locked" + Test = { + $script = $commonPath + "5.4.2.8.sh" + bash $script + if ($?) { + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "5.4.3.1" + Task = "Ensure nologin is not listed in /etc/shells" + Test = { + $script = $commonPath + "5.4.3.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.3.2" + Task = "Ensure default user shell timeout is configured" + Test = { + $script = $commonPath + "5.4.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "5.4.3.3" + Task = "Ensure default user umask is configured" + Test = { + $script = $commonPath + "5.4.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.1.1" + Task = "Ensure permissions on /etc/passwd are configured" + Test = { + $test1 = stat -c '%#a' /etc/passwd | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.1.2" + Task = "Ensure permissions on /etc/passwd- are configured" + Test = { + $test1 = stat -c '%#a' /etc/passwd- | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.1.3" + Task = "Ensure cryptographic mechanisms are used to protect the integrity of audit tools" + Test = { + $script = $commonPath + "6.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.1.1.1" + Task = "Ensure journald service is enabled and active" + Test = { + $test1 = systemctl is-enabled rsyslog + if($test1 -match "enabled"){ + return @{ + Message = "Compliant" + Status = "True" + } + } + return @{ + Message = "Not-Compliant" + Status = "False" + } + } +} +[AuditTest] @{ + Id = "6.2.1.1.2" + Task = "Ensure journald log file access is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "6.2.1.1.3" + Task = "Ensure journald log file rotation is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "6.2.1.1.4" + Task = "Ensure journald ForwardToSyslog is disabled" + Test = { + $script = $scriptPath + "6.2.1.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.1.1.5" + Task = "Ensure journald Storage is configured" + Test = { + $script = $scriptPath + "6.2.1.1.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.1.1.6" + Task = "Ensure journald Compress is configured" + Test = { + $script = $scriptPath + "6.2.1.1.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.1.2.1" + Task = "Ensure systemd-journal-remote is installed" + Test = { + $test1 = Test-PackageInstalled -PackageName systemd-journal-remote + if($test1){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ + Id = "6.2.1.2.2" + Task = "Ensure systemd-journal-remote authentication is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ + Id = "6.2.1.2.3" + Task = "Ensure systemd-journal-upload is enabled and active" + Test = { + $test1 = systemctl is-enabled systemd-journal-upload.service + $test2 = systemctl is-active systemd-journal-upload.service + if($test1 -eq "enabled" -and $test2 -match "active"){ + return $retCompliant + } + return $retCompliant + } +} +[AuditTest] @{ + Id = "6.2.1.2.4" + Task = "Ensure systemd-journal-remote service is not in use" + Test = { + $script = $scriptPath + "6.2.1.2.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.2.2.1" + Task = "Ensure access to all logfiles has been configured" + Test = { + $fileListAll = find /var/log -type f -ls + $fileListFiltered = find /var/log -type f -ls | grep "\-....\-\-\-\-\-" + if($fileListAll.Count -eq $fileListFiltered.Count){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.1.1" + Task = "Ensure auditd packages are installed" + Test = { + $test1 = Test-PackageInstalled -PackageName auditd + $test2 = Test-PackageInstalled -PackageName audispd-plugins + if($test1 -and $test2){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.1.2" + Task = "Ensure auditd service is enabled and active" + Test = { + $test1 = systemctl is-enabled auditd + if($test1 -match "enabled"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.1.3" + Task = "Ensure auditing for processes that start prior to auditd is enabled" + Test = { + $script = $scriptPath + "6.3.1.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.1.4" + Task = "Ensure audit_backlog_limit is sufficient" + Test = { + $script = $scriptPath + "6.3.1.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.2.1" + Task = "Ensure audit log storage size is configured" + Test = { + $script = $commonPath + "6.3.2.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.2.2" + Task = "Ensure audit logs are not automatically deleted" + Test = { + $script = $commonPath + "6.3.2.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.2.3" + Task = "Ensure system is disabled when audit logs are full" + Test = { + $test1 = grep -Pi -- '^\h*disk_full_action\h*=\h*(halt|single)\b' /etc/audit/auditd.conf + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.2.4" + Task = "Ensure system warns when audit logs are low on space" + Test = { + $test1 = grep -Pi -- '^\h*space_left_action\h*=\h*\w+\b' /etc/audit/auditd.conf | awk '{print $3}' + if($test1 -match "^(email|exec|single|halt)$"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.3.1" + Task = "Ensure changes to system administration scope is collected" + Test = { + $script = $commonPath + "6.3.3.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.2" + Task = "Ensure actions as another user are always logged" + Test = { + $script = $commonPath + "6.3.3.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.3" + Task = "Ensure events that modify the sudo log file are collected" + Test = { + $script = $commonPath + "6.3.3.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.4" + Task = "Ensure events that modify date and time information are collected" + Test = { + $script = $commonPath + "6.3.3.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.5" + Task = "Ensure events that modify the system's network environment are collected" + Test = { + $script = $commonPath + "6.3.3.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.6" + Task = "Ensure use of privileged commands are collected" + Test = { + $script = $commonPath + "6.3.3.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.7" + Task = "Ensure unsuccessful file access attempts are collected" + Test = { + $script = $commonPath + "6.3.3.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.8" + Task = "Ensure events that modify user/group information are collected" + Test = { + $script = $commonPath + "6.3.3.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.9" + Task = "Ensure discretionary access control permission modification events are collected" + Test = { + $script = $commonPath + "6.3.3.9.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.10" + Task = "Ensure successful file system mounts are collected" + Test = { + $script = $commonPath + "6.3.3.10.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.11" + Task = "Ensure session initiation information is collected" + Test = { + $path1 = $scriptPath + "4.1.3.11_1.sh" + $result11 = bash $path1 | grep "\-w /var/run/utmp -p wa -k session" + $result12 = bash $path1 | grep "\-w /var/log/wtmp -p wa -k session" + $result13 = bash $path1 | grep "\-w /var/log/btmp -p wa -k session" + $path2 = $scriptPath + "4.1.3.11_2.sh" + $result21 = bash $path2 | grep "\-w /var/run/utmp -p wa -k session" + $result22 = bash $path2 | grep "\-w /var/log/wtmp -p wa -k session" + $result23 = bash $path2 | grep "\-w /var/log/btmp -p wa -k session" + if($result11 -ne $null -and $result12 -ne $null -and $result13 -ne $null -and $result21 -ne $null -and $result22 -ne $null -and $result23 -ne $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.3.12" + Task = "Ensure login and logout events are collected" + Test = { + $script = $commonPath + "6.3.3.12.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.13" + Task = "Ensure file deletion events by users are collected" + Test = { + $script = $commonPath + "6.3.3.13.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.14" + Task = "Ensure events that modify the system's Mandatory Access Controls are collected" + Test = { + $script = $commonPath + "6.3.3.14.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.15" + Task = "Ensure successful and unsuccessful attempts to use the chcon command are recorded" + Test = { + $script = $commonPath + "6.3.3.15.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.16" + Task = "Ensure successful and unsuccessful attempts to use the setfacl command are recorded" + Test = { + $script = $commonPath + "6.3.3.16.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.17" + Task = "Ensure successful and unsuccessful attempts to use the chacl command are recorded" + Test = { + $script = $commonPath + "6.3.3.17.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.18" + Task = "Ensure successful and unsuccessful attempts to use the usermod command are recorded" + Test = { + $script = $commonPath + "6.3.3.18.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.19" + Task = "Ensure kernel module loading unloading and modification is collected" + Test = { + $script = $commonPath + "6.3.3.19.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.3.20" + Task = "Ensure the audit configuration is immutable" + Test = { + $test1 = grep "^\s*[^#]" /etc/audit/rules.d/*.rules | tail -l + if($test1 -match "-e 2"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.3.21" + Task = "Ensure the running and on disk configuration is the same" + Test = { + $test1 = augenrules --check + if($test1 -match "/usr/sbin/augenrules: No change"){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "6.3.4.1" + Task = "Ensure audit log files mode is configured" + Test = { + $script = $scriptPath + "6.3.4.1.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.2" + Task = "Ensure audit log files owner is configured" + Test = { + $script = $scriptPath + "6.3.4.2.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.3" + Task = "Ensure audit log files group owner is configured" + Test = { + $script = $scriptPath + "6.3.4.3.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.4" + Task = "Ensure the audit log file directory mode is configured" + Test = { + $script = $scriptPath + "6.3.4.4.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.5" + Task = "Ensure audit configuration files mode is configured" + Test = { + $script = $commonPath + "6.3.4.5.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.6" + Task = "Ensure audit configuration files owner is configured" + Test = { + $script = $commonPath + "6.3.4.6.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.7" + Task = "Ensure audit configuration files group owner is configured" + Test = { + $script = $commonPath + "6.3.4.7.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.8" + Task = "Ensure audit tools mode is configured" + Test = { + $script = $commonPath + "6.3.4.8.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.9" + Task = "Ensure audit tools owner is configured" + Test = { + $script = $commonPath + "6.3.4.9.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "6.3.4.10" + Task = "Ensure audit tools group owner is configured" + Test = { + $test1 = stat -Lc '%G' /sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules | awk '$1 != "root" {print}' + if($test1 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.1" + Task = "Ensure permissions on /etc/passwd are configured" + Test = { + $test1 = stat -c '%#a' /etc/passwd | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.2" + Task = "Ensure permissions on /etc/passwd- are configured" + Test = { + $test1 = stat -c '%#a' /etc/passwd- | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.3" + Task = "Ensure permissions on /etc/group are configured" + Test = { + $test1 = stat -c '%#a' /etc/group | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.4" + Task = "Ensure permissions on /etc/group- are configured" + Test = { + $test1 = stat -c '%#a' /etc/group- | grep -q "0644" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.5" + Task = "Ensure permissions on /etc/shadow are configured" + Test = { + $test1 = stat -c '%#a' /etc/shadow | grep -q "0640" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.6" + Task = "Ensure permissions on /etc/shadow- are configured" + Test = { + $test1 = stat -c '%#a' /etc/shadow- | grep -q "0640" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.7" + Task = "Ensure permissions on /etc/gshadow are configured" + Test = { + $test1 = stat -c '%#a' /etc/gshadow | grep -q "0640" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.8" + Task = "Ensure permissions on /etc/gshadow- are configured" + Test = { + $test1 = stat -c '%#a' /etc/gshadow- | grep -q "0640" + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.9" + Task = "Ensure permissions on /etc/shells are configured" + Test = { + $script = $commonPath + "7.1.9.sh" + bash $script + if ($?) { + return $retCompliant + } else { + return $retNonCompliant + } + } +} +[AuditTest] @{ + Id = "7.1.10" + Task = "Ensure permissions on /etc/security/opasswd are configured" + Test = { + $script = $commonPath + "7.1.10.sh" + $result = bash $script + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.11" + Task = "Ensure world writable files and directories are secured" + Test = { + #$partitions = mapfile -t partitions < (sudo fdisk -l | grep -o '/dev/[^ ]*') + #$test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -0002 + $script = $commonPath + "7.1.11.sh" + $result = bash $script + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.12" + Task = "Ensure no files or directories without an owner and a group exist" + Test = { + $script = $commonPath + "7.1.12.sh" + $result = bash $script + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.1.13" + Task = "Ensure SUID and SGID files are reviewed" + Test = { + $test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -4000 + $message = "" + foreach($line in $test1){ + $message += "
$line" + } + return @{ + Message = "Please review following list of files: $($message)" + Status = "None" + } + } +} +[AuditTest] @{ + Id = "7.2.1" + Task = "Ensure accounts in /etc/passwd use shadowed passwords" + Test = { + $test1 = awk -F: '($2 != "x" ) { print $1 " is not set to shadowed passwords "}'/etc/passwd + if($test1 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.2" + Task = "Ensure /etc/shadow password fields are not empty" + Test = { + $test1 = awk -F: '($2 == "" ) { print $1 " does not have a password "}' /etc/shadow + if($test1 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.3" + Task = "Ensure all groups in /etc/passwd exist in /etc/group" + Test = { + $path = $scriptPath + "6.2.3.sh" + $result = bash $path + if($?){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.4" + Task = "Ensure shadow group is empty" + Test = { + $test1 = awk -F: '($1=="shadow") {print $NF}' /etc/group + $test2 = awk -F: -v GID="$(awk -F: '($1=="shadow") {print $3}' /etc/group)" '($4==GID) {print $1}' /etc/passwd + if($test1.Length -eq 0 -and $test2 -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.5" + Task = "Ensure no duplicate UIDs exist" + Test = { + $path = $scriptPath + "6.2.5.sh" + $result = bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.6" + Task = "Ensure no duplicate GIDs exist" + Test = { + $path = $scriptPath + "6.2.6.sh" + $result = bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.7" + Task = "Ensure no duplicate user names exist" + Test = { + $path = $scriptPath + "6.2.7.sh" + $result = bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} +[AuditTest] @{ + Id = "7.2.8" + Task = "Ensure no duplicate group names exist" + Test = { + $path = $scriptPath + "6.2.8.sh" + $result = bash $path + if($result -eq $null){ + return $retCompliant + } + return $retNonCompliant + } +} + +[AuditTest] @{ # in CIS it's automated, but in Excelsheet it's manual + Id = "7.2.9" + Task = "Ensure local interactive user home directories are configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} +[AuditTest] @{ # in CIS it's automated, but in Excelsheet it's manual + Id = "7.2.10" + Task = "Ensure local interactive user dot files access is configured" + Test = { + return $retNonCompliantManualReviewRequired + } +} diff --git a/ATAPAuditor/Helpers/AuditGroupFunctions.ps1 b/ATAPAuditor/Helpers/AuditGroupFunctions.ps1 new file mode 100644 index 0000000..c01eef9 --- /dev/null +++ b/ATAPAuditor/Helpers/AuditGroupFunctions.ps1 @@ -0,0 +1,543 @@ +# Begin Helper for version control +function isWindows8OrNewer { + return ([Environment]::OSVersion.Version -ge (New-Object 'Version' 6, 2)) +} +function isWindows81OrNewer { + return ([Environment]::OSVersion.Version -ge (New-Object 'Version' 6, 3)) +} +function isWindows10OrNewer { + return ([Environment]::OSVersion.Version -ge (New-Object 'Version' 10, 0)) +} +function win7NoTPMChipDetected { + return (Get-CimInstance -ClassName Win32_Tpm -Namespace root\cimv2\security\microsofttpm | Select-Object -ExpandProperty IsActivated_InitialValue) -eq $null +} + +$sbdIndex = 1 +function IncrementSecurityBaseDataCounter { + return $sbdIndex++ +} + + +function hasTPM { + try { + $obj = (Get-Tpm).TpmPresent + } + catch { + return $null + } + return $obj +} +# End Helper for version control +function isWindows10Enterprise { + $os = Get-ComputerInfo OsName + if ($os -match "Windows 10 Enterprise" -or $os -match "Windows 11 Enterprise") { + return $true + } + return $false +} + +#Helper function for 'Test-ASRRules' +Function Test-RegistryValue ($regkey, $name) { + if (Get-ItemProperty -Path $regkey -Name $name -ErrorAction Ignore) { + $true + } + else { + $false + } +} + +#This function is needed in AuditGroups, which check both paths of ASR-Rules. +function Test-ASRRules { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [String] $Path, + [Parameter(Mandatory = $true)] + [String] $Value + ) + + process { + try { + if (Test-Path -Path $Path) { + return Test-RegistryValue $Path $Value + } + else { + return $false + } + } + catch { + + } + } + +} + +function Test-MultiplePaths { + [CmdletBinding()] + [OutputType([Object])] + param ( + [Parameter(Mandatory = $True, ValueFromPipeline)] + [String] + $Path, + [Parameter(Mandatory = $True)] + [String] + $Key, + [Parameter(Mandatory = $True)] + [Object] + $ExpectedValue, + [PSCustomObject] + $Result = @{ + Message = "Registry value not found." + Status = "False" + } + ) + PROCESS { + $regValue = Get-ItemProperty -ErrorAction SilentlyContinue ` + -Path $Path ` + -Name $Key ` + | Select-Object -ExpandProperty "$($Key)" + # if regValue == expectedValue + if (($regValue -eq $ExpectedValue)) { + $Result = @{ + Message = "Compliant" + Status = "True" + } + } + # if regValue isnot empty AND regValue isnot expectedValue AND result is not True (yet) + # This result is ranked #2 below "Compliant" and above "Registry value not found" + if (($null -ne $regValue) -and ($regValue -ne $ExpectedValue) -and ($Result.Status -ne "True")) { + $Result = @{ + Message = "Registry value is '$regValue'. Expected: $ExpectedValue" + Status = "False" + } + } + } + END { + return $Result + } +} + +#Returns Hyper-V status +function CheckHyperVStatus { + return (Get-WindowsOptionalFeature -Online -FeatureName "Microsoft-Hyper-V").State +} + +function CheckWindefRunning { + # for systems, won't work if server + try { + $defStatus = (Get-MpComputerStatus -ErrorAction Ignore | Select-Object AMRunningMode) + if ($defStatus.AMRunningMode -eq "Normal") { + return $true + } + } + catch { + <#Do this if a terminating exception happens#> + } + + # for standalone systems, won't work if server + try { + $defStatus = (Get-MpComputerStatus -ErrorAction Ignore) + if ($defStatus.AMServiceEnabled -eq $true -and $defStatus.AntispywareEnabled -eq $true -and $defStatus.AntivirusEnabled -eq $true -and $defStatus.NISEnabled -eq $true -and $defStatus.RealTimeProtectionEnabled -eq $true) { + return $true + } + } + catch { + <#Do this if a terminating exception happens#> + } + + # for servers, won't work if standalone system + try { + if ((Get-WindowsFeature -Name Windows-Defender -ErrorAction Ignore).installed) { + if ((Get-Service -Name windefend -ErrorAction Ignore).Status -eq "Running") { + return $true + } + } + } + catch { + <#Do this if a terminating exception happens#> + } + + return $false +} + +function CheckForActiveAV { + $result = $false + $av = Get-AntiVirusStatus + foreach ($a in $av) { + if (($a.'Definition Status') -eq "Enabled") { + $result = $true; + } + } + return $result +} + +# only works for desktop workstations, not servers (except Windows XP and older) +function Get-AntiVirusStatus { + try { + $AntiVirusProducts = Get-WmiObject -Namespace "root\SecurityCenter2" -Class AntiVirusProduct -ComputerName $env:computername -ErrorAction Stop + } + catch [System.Management.ManagementException] { + <#Do this if a terminating exception happens#> + } + + $result = @() + foreach ($AntiVirusProduct in $AntiVirusProducts) { + + $hex = '0x{0:x}' -f $AntiVirusProduct.productState + $avstatus = $hex.Substring(3, 2) + $defstatus = "Unknown" + if (($avstatus -eq "00") -or ($avstatus -eq "01")) { + $defstatus = "Disabled" + } + if (($avstatus -eq "10") -or ($avstatus -eq "11")) { + $defstatus = "Enabled" + } + + $avupdated = $hex.Substring(5, 2) + $avupdatestatus = "Unknown" + if ($avupdated -eq ("10")) { + $avupdatestatus = "Not Up-to-date" + } + if ($avupdated -eq ("00")) { + $avupdatestatus = "Up-to-date" + } + + # hashtable for av status + $ht = @{} + $ht.Name = $AntiVirusProduct.displayName + $ht.'Definition Status' = $defstatus + $ht.'Update Status' = $avupdatestatus + + # add new hashtable to result + $result += New-Object -TypeName PSObject -Property $ht + } + return $result +} + +function getListOfWeakCipherSuites { + $listOfWeakCipherSuites = @( + "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", + "TLS_DH_DSS_WITH_AES_128_CBC_SHA", + "TLS_DH_DSS_WITH_AES_128_CBC_SHA256", + "TLS_DH_DSS_WITH_AES_128_GCM_SHA256", + "TLS_DH_DSS_WITH_AES_256_CBC_SHA", + "TLS_DH_DSS_WITH_AES_256_CBC_SHA256", + "TLS_DH_DSS_WITH_AES_256_GCM_SHA384", + "TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256", + "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256", + "TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384", + "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384", + "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", + "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256", + "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", + "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", + "TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384", + "TLS_DH_DSS_WITH_SEED_CBC_SHA", + "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", + "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", + "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", + "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", + "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", + "TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256", + "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256", + "TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384", + "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384", + "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", + "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256", + "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", + "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", + "TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384", + "TLS_DHE_DSS_WITH_SEED_CBC_SHA", + "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", + "TLS_DHE_PSK_WITH_AES_128_CBC_SHA", + "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", + "TLS_DHE_PSK_WITH_AES_128_CCM", + "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", + "TLS_DHE_PSK_WITH_AES_256_CBC_SHA", + "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", + "TLS_DHE_PSK_WITH_AES_256_CCM", + "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", + "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256", + "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256", + "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384", + "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384", + "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", + "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", + "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", + "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_DHE_RSA_WITH_AES_128_CCM", + "TLS_DHE_RSA_WITH_AES_128_CCM_8", + "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", + "TLS_DHE_RSA_WITH_AES_256_CCM", + "TLS_DHE_RSA_WITH_AES_256_CCM_8", + "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256", + "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256", + "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384", + "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384", + "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", + "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", + "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", + "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", + "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", + "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "TLS_DHE_RSA_WITH_SEED_CBC_SHA", + "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_DH_RSA_WITH_AES_128_CBC_SHA", + "TLS_DH_RSA_WITH_AES_128_CBC_SHA256", + "TLS_DH_RSA_WITH_AES_128_GCM_SHA256", + "TLS_DH_RSA_WITH_AES_256_CBC_SHA", + "TLS_DH_RSA_WITH_AES_256_CBC_SHA256", + "TLS_DH_RSA_WITH_AES_256_GCM_SHA384", + "TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256", + "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256", + "TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384", + "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384", + "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", + "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256", + "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", + "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", + "TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384", + "TLS_DH_RSA_WITH_SEED_CBC_SHA", + "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", + "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", + "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256", + "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256", + "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384", + "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384", + "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", + "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", + "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256", + "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384", + "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", + "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", + "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", + "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256", + "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384", + "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", + "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256", + "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384", + "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", + "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", + "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256", + "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256", + "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384", + "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384", + "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256", + "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384", + "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384", + "TLS_KRB5_WITH_3DES_EDE_CBC_SHA", + "TLS_KRB5_WITH_IDEA_CBC_SHA", + "TLS_PSK_DHE_WITH_AES_128_CCM_8", + "TLS_PSK_DHE_WITH_AES_256_CCM_8", + "TLS_PSK_WITH_3DES_EDE_CBC_SHA", + "TLS_PSK_WITH_AES_128_CBC_SHA", + "TLS_PSK_WITH_AES_128_CBC_SHA256", + "TLS_PSK_WITH_AES_128_CCM", + "TLS_PSK_WITH_AES_128_CCM_8", + "TLS_PSK_WITH_AES_128_GCM_SHA256", + "TLS_PSK_WITH_AES_256_CBC_SHA", + "TLS_PSK_WITH_AES_256_CBC_SHA384", + "TLS_PSK_WITH_AES_256_CCM", + "TLS_PSK_WITH_AES_256_CCM_8", + "TLS_PSK_WITH_AES_256_GCM_SHA384", + "TLS_PSK_WITH_ARIA_128_CBC_SHA256", + "TLS_PSK_WITH_ARIA_128_GCM_SHA256", + "TLS_PSK_WITH_ARIA_256_CBC_SHA384", + "TLS_PSK_WITH_ARIA_256_GCM_SHA384", + "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256", + "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", + "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384", + "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256", + "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", + "TLS_RSA_PSK_WITH_AES_128_CBC_SHA", + "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", + "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", + "TLS_RSA_PSK_WITH_AES_256_CBC_SHA", + "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", + "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", + "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256", + "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256", + "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384", + "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384", + "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256", + "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", + "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384", + "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", + "TLS_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_RSA_WITH_AES_128_CBC_SHA", + "TLS_RSA_WITH_AES_128_CBC_SHA256", + "TLS_RSA_WITH_AES_128_CCM", + "TLS_RSA_WITH_AES_128_CCM_8", + "TLS_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_CBC_SHA", + "TLS_RSA_WITH_AES_256_CBC_SHA256", + "TLS_RSA_WITH_AES_256_CCM", + "TLS_RSA_WITH_AES_256_CCM_8", + "TLS_RSA_WITH_AES_256_GCM_SHA384", + "TLS_RSA_WITH_ARIA_128_CBC_SHA256", + "TLS_RSA_WITH_ARIA_128_GCM_SHA256", + "TLS_RSA_WITH_ARIA_256_CBC_SHA384", + "TLS_RSA_WITH_ARIA_256_GCM_SHA384", + "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", + "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256", + "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", + "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", + "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384", + "TLS_RSA_WITH_IDEA_CBC_SHA", + "TLS_RSA_WITH_SEED_CBC_SHA", + "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", + "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", + "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", + "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", + "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", + "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", + "TLS_SRP_SHA_WITH_AES_128_CBC_SHA", + "TLS_SRP_SHA_WITH_AES_256_CBC_SHA" + ) + return $listOfWeakCipherSuites +} + +function getListOfInsecureCipherSuites { + $listOfInsecureCipherSuites = @( + "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA", + "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5", + "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA", + "TLS_DH_anon_WITH_AES_128_CBC_SHA", + "TLS_DH_anon_WITH_AES_128_CBC_SHA256", + "TLS_DH_anon_WITH_AES_128_GCM_SHA256", + "TLS_DH_anon_WITH_AES_256_CBC_SHA", + "TLS_DH_anon_WITH_AES_256_CBC_SHA256", + "TLS_DH_anon_WITH_AES_256_GCM_SHA384", + "TLS_DH_anon_WITH_ARIA_128_CBC_SHA256", + "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256", + "TLS_DH_anon_WITH_ARIA_256_CBC_SHA384", + "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384", + "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA", + "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", + "TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256", + "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", + "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256", + "TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384", + "TLS_DH_anon_WITH_DES_CBC_SHA", + "TLS_DH_anon_WITH_RC4_128_MD5", + "TLS_DH_anon_WITH_SEED_CBC_SHA", + "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", + "TLS_DH_DSS_WITH_DES_CBC_SHA", + "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", + "TLS_DHE_DSS_WITH_DES_CBC_SHA", + "TLS_DHE_PSK_WITH_NULL_SHA", + "TLS_DHE_PSK_WITH_NULL_SHA256", + "TLS_DHE_PSK_WITH_NULL_SHA384", + "TLS_DHE_PSK_WITH_RC4_128_SHA", + "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", + "TLS_DHE_RSA_WITH_DES_CBC_SHA", + "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", + "TLS_DH_RSA_WITH_DES_CBC_SHA", + "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", + "TLS_ECDH_anon_WITH_AES_128_CBC_SHA", + "TLS_ECDH_anon_WITH_AES_256_CBC_SHA", + "TLS_ECDH_anon_WITH_NULL_SHA", + "TLS_ECDH_anon_WITH_RC4_128_SHA", + "TLS_ECDH_ECDSA_WITH_NULL_SHA", + "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", + "TLS_ECDHE_ECDSA_WITH_NULL_SHA", + "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", + "TLS_ECDHE_PSK_WITH_NULL_SHA", + "TLS_ECDHE_PSK_WITH_NULL_SHA256", + "TLS_ECDHE_PSK_WITH_NULL_SHA384", + "TLS_ECDHE_PSK_WITH_RC4_128_SHA", + "TLS_ECDHE_RSA_WITH_NULL_SHA", + "TLS_ECDHE_RSA_WITH_RC4_128_SHA", + "TLS_ECDH_RSA_WITH_NULL_SHA", + "TLS_ECDH_RSA_WITH_RC4_128_SHA", + "TLS_GOSTR341112_256_WITH_28147_CNT_IMIT", + "TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC", + "TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L", + "TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S", + "TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC", + "TLS_GOSTR341112_256_WITH_MAGMA_MGM_L", + "TLS_GOSTR341112_256_WITH_MAGMA_MGM_S", + "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", + "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", + "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", + "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", + "TLS_KRB5_EXPORT_WITH_RC4_40_MD5", + "TLS_KRB5_EXPORT_WITH_RC4_40_SHA", + "TLS_KRB5_WITH_3DES_EDE_CBC_MD5", + "TLS_KRB5_WITH_DES_CBC_MD5", + "TLS_KRB5_WITH_DES_CBC_SHA", + "TLS_KRB5_WITH_IDEA_CBC_MD5", + "TLS_KRB5_WITH_RC4_128_MD5", + "TLS_KRB5_WITH_RC4_128_SHA", + "TLS_NULL_WITH_NULL_NULL", + "TLS_PSK_WITH_NULL_SHA", + "TLS_PSK_WITH_NULL_SHA256", + "TLS_PSK_WITH_NULL_SHA384", + "TLS_PSK_WITH_RC4_128_SHA", + "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", + "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5", + "TLS_RSA_EXPORT_WITH_RC4_40_MD5", + "TLS_RSA_PSK_WITH_NULL_SHA", + "TLS_RSA_PSK_WITH_NULL_SHA256", + "TLS_RSA_PSK_WITH_NULL_SHA384", + "TLS_RSA_PSK_WITH_RC4_128_SHA", + "TLS_RSA_WITH_DES_CBC_SHA", + "TLS_RSA_WITH_NULL_MD5", + "TLS_RSA_WITH_NULL_SHA", + "TLS_RSA_WITH_NULL_SHA256", + "TLS_RSA_WITH_RC4_128_MD5", + "TLS_RSA_WITH_RC4_128_SHA", + "TLS_SHA256_SHA256", + "TLS_SHA384_SHA384", + "TLS_SM4_CCM_SM3", + "TLS_SM4_GCM_SM3" + ) + return $listOfInsecureCipherSuites +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/Firewall.ps1 b/ATAPAuditor/Helpers/Firewall.ps1 new file mode 100644 index 0000000..ac89d47 --- /dev/null +++ b/ATAPAuditor/Helpers/Firewall.ps1 @@ -0,0 +1,83 @@ +function Test-FirewallPaths { + [CmdletBinding()] + [OutputType([Object])] + param ( + [Parameter(Mandatory = $True, ValueFromPipeline)] + [String] + $Path, + [Parameter(Mandatory = $True)] + [String] + $Key, + [Parameter(Mandatory = $True)] + [Object] + $ExpectedValue, + [Parameter(Mandatory = $True)] + [String] + $ProfileType, + [PSCustomObject] + $Result = @{ + Message = "Registry value not found." + Status = "False" + } + ) + BEGIN { + $FirewallProfiles = Get-NetFirewallProfile -ErrorAction SilentlyContinue + } + PROCESS { + $regValue = Get-ItemProperty -ErrorAction SilentlyContinue ` + -Path $Path ` + -Name $Key ` + | Select-Object -ExpandProperty "$($Key)" + # if regValue == expectedValue OR if the LogFilePath ends with .log + if (($regValue -eq $ExpectedValue) -or (($Key -eq "LogFilePath") -and ($regValue -match "[a-z]*.log"))) { + $Result = @{ + Message = "Compliant" + Status = "True" + } + } + # if regValue isnot empty AND regValue isnot expectedValue AND result is not True (yet) + # This result is ranked #2 below "Compliant" and above "Registry value not found" + if (($null -ne $regValue) -and ($regValue -ne $ExpectedValue) -and ($Result.Status -ne "True")) { + $Result = @{ + Message = "Registry value is '$regValue'. Expected: $ExpectedValue" + Status = "False" + } + } + } + END { + $FirewallProfile = $FirewallProfiles | Where-Object {$_.Name -eq $ProfileType} + $FirewallProfileValue = $FirewallProfile.$Key + # check whether value is a number + if ($FirewallProfileValue -is [int32] -or $FirewallProfileValue -is [uint32] -or $FirewallProfileValue -is [int64] -or $FirewallProfileValue -is [uint64]) { + # if value is a number, the value may also be greater and equals to the expectedvalue + if ($FirewallProfileValue -ge $expectedValue) { + $Result = @{ + Message = "Compliant" + Status = "True" + } + } + } + if ($FirewallProfileValue -eq $expectedValue) { + $Result = @{ + Message = "Compliant" + Status = "True" + } + } + if ($Key -eq "LogFilePath") { + if ($FirewallProfiles -eq $null -or $FirewallProfiles.Count -lt 3) { + ### if profiles are empty, skip comparison and continue with other checks + } else { + if (($FirewallProfiles[0].LogFileName -eq $FirewallProfiles[1].LogFileName) -or + ($FirewallProfiles[0].LogFileName -eq $FirewallProfiles[2].LogFileName) -or + ($FirewallProfiles[1].LogFileName -eq $FirewallProfiles[2].LogFileName)) { + $Result = @{ + Message = "For better organization and identification of specific issues within each profile consider using separate logfiles for each profile." + Status = "Warning" + } + } + } + } + return $Result + } +} + diff --git a/ATAPAuditor/Helpers/HashHelper.ps1 b/ATAPAuditor/Helpers/HashHelper.ps1 new file mode 100644 index 0000000..fec6ba2 --- /dev/null +++ b/ATAPAuditor/Helpers/HashHelper.ps1 @@ -0,0 +1,58 @@ +#Hash functions will be used for hashing results of report +#Based on SHA-256 and SHA-512 + +function Get-SHA256Hash { + Param ( + [Parameter(Mandatory=$true)] + [string] + $ClearString + ) + + $hasher = [System.Security.Cryptography.HashAlgorithm]::Create('sha256') + $hash = $hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($ClearString)) + + $hashString = [System.BitConverter]::ToString($hash) + $hashString.Replace('-', '') +} + +function GenerateHashTable{ + Param ( + [Parameter(Mandatory=$true)] + [Report] + $report + ) + + #hashes for each recommendation + $hashtable_sha256 = @{} + foreach($recommendation in $report.Sections){ + $hash_sha256 = "" + foreach($section in $recommendation.SubSections){ + foreach($test in $section.AuditInfos){ + #hash each test status + $statusHash_sha256 = (Get-SHA256Hash $test.Status) + $hash_sha256 += $statusHash_sha256 + #hash combination of tests + $hash_sha256 = (Get-SHA256Hash $hash_sha256) + } + } + #add final hash to hashlist + $hashtable_sha256.add($recommendation.Title, $hash_sha256) + } + + #checksum hash for overal check + $overallHash_sha256 = "" + foreach($hash in $hashtable_sha256.values){ + #add recommendation hash to overall hash + $overallHash_sha256 += $hash + #hash this value again + try{ + $overallHash_sha256 = Get-SHA256Hash $overallHash_sha256 -ErrorAction Stop + } + catch{ + Write-Warning "Hash code for report section couldn't be created." + } + } + + $hashtable_sha256.add($report.Title, $overallHash_sha256) + return $hashtable_sha256 +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/LinuxHelper.ps1 b/ATAPAuditor/Helpers/LinuxHelper.ps1 new file mode 100644 index 0000000..348ce23 --- /dev/null +++ b/ATAPAuditor/Helpers/LinuxHelper.ps1 @@ -0,0 +1,106 @@ +$script:LinuxDistroId = $null + + +$rcTrue = "True" +$rcCompliant = "Compliant" +$rcFalse = "False" +$rcNone = "None" +$rcNonCompliant = "Non-Compliant" +$rcNonCompliantManualReviewRequired = "Manual review required" +$rcCompliantIPv6isDisabled = "IPv6 is disabled" + +if (Test-Path "/etc/os-release") { + $osRelease = @{} + Get-Content "/etc/os-release" | ForEach-Object { + if ($_ -match "^(?\w+)=(?.+)$") { + $osRelease[$matches.key] = $matches.val.Trim('"') + } + } + + $script:LinuxDistroId = $osRelease["ID"] + + if (-not $script:LinuxDistroId) { + throw "Could not detect Linux distribution from /etc/os-release" + } + + switch ($script:LinuxDistroId) { + "ubuntu" {} + "debian" {} + "rhel" {} + "centos" {} + "fedora" {} + "opensuse" {} + default { + throw "Unsupported Linux distribution: $script:LinuxDistroId" + } + } + Write-Verbose "Detected $script:LinuxDistroId" +} else { + throw "/etc/os-release not found. Cannot detect Linux distribution." +} + +function Test-PackageInstalled { + param ( + [Parameter(Mandatory = $true)] + [string]$PackageName + ) + + switch ($script:LinuxDistroId) { + "ubuntu" + { + dpkg-query -W -f='${db:Status-Abbrev}' $PackageName 2>/dev/null | Out-Null + return ($LASTEXITCODE -eq 0) + } + + "debian" + { + dpkg-query -W -f='${db:Status-Abbrev}' $PackageName 2>/dev/null | Out-Null + return ($LASTEXITCODE -eq 0) + } + + "rhel" + { + rpm -q $PackageName >/dev/null 2>&1 + return ($LASTEXITCODE -eq 0) + } + + "centos" + { + rpm -q $PackageName >/dev/null 2>&1 + return ($LASTEXITCODE -eq 0) + } + + "fedora" + { + rpm -q $PackageName >/dev/null 2>&1 + return ($LASTEXITCODE -eq 0) + } + + "opensuse" + { + rpm -q $PackageName >/dev/null 2>&1 + return ($LASTEXITCODE -eq 0) + } + + default + { throw "Unexpected distro in module runtime: $script:LinuxDistroId" } + } +} + +function Test-ServiceActiveOrEnabled { + param ( + [Parameter(Mandatory = $true)] + [string]$ServiceName + ) + + # Check if the service is active + systemctl is-active --quiet $ServiceName + $isActive = ($LASTEXITCODE -eq 0) + + # Check if the service is enabled + systemctl is-enabled --quiet $ServiceName + $isEnabled = ($LASTEXITCODE -eq 0) + + return ($isActive -or $isEnabled) +} + diff --git a/ATAPAuditor/Helpers/LogFile.ps1 b/ATAPAuditor/Helpers/LogFile.ps1 new file mode 100644 index 0000000..3f6af1b --- /dev/null +++ b/ATAPAuditor/Helpers/LogFile.ps1 @@ -0,0 +1,94 @@ +function Set-LogFile { + [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] + Param( + [Parameter(Mandatory = $true)] + [Alias('LogPath')] + [string]$Path, + [Parameter(Mandatory = $true)] + [Alias('Logname')] + [string]$Name + ) + + $FullPath = Get-FullPath $Path $Name + + # Create file if it does not already exists + if (!(Test-Path -Path $FullPath)) { + + # Create file and start logging + New-Item -Path $FullPath -ItemType File -Force | Out-Null + + Add-Content -Path $FullPath -Value "***************************************************************************************************" + Add-Content -Path $FullPath -Value " Logfile created at [$([DateTime]::Now)]" + Add-Content -Path $FullPath -Value "***************************************************************************************************" + Add-Content -Path $FullPath -Value "" + Add-Content -Path $FullPath -Value "" + } +} + +function Write-LogFile { + [CmdletBinding()] + Param( + [Parameter(Mandatory = $true)] + [Alias('LogMessage')] + [string]$Message, + + [Parameter(Mandatory = $true)] + [Alias('LogPath')] + [string]$Path, + + [Parameter(Mandatory = $true)] + [Alias('Logname')] + [string]$Name, + + [ValidateSet("Error", "Warning", "Info")] + [string]$Level = "Info" + ) + + + Set-LogFile $Path $Name + $FullPath = Get-FullPath $Path $Name + + # Format date for log file + $FormattedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" + + switch ($Level) { + 'Error' { + # Write-Error $Message + $LevelText = '[ERROR]:' + } + 'Warning' { + # Write-Warning $Message + $LevelText = '[WARNING]:' + } + 'Info' { + # Write-Verbose $Message + $LevelText = '[INFO]:' + } + } + Add-Content $FullPath "$FormattedDate $LevelText" + Add-Content $FullPath "$Message" + Add-Content $FullPath "--------------------------" + Add-Content $FullPath "" +} + +function Get-FullPath { + [CmdletBinding()] + Param( + [Parameter(Mandatory = $true)] + [string]$Path, + [Parameter(Mandatory = $true)] + [string]$File + ) + + $FullPath = "" + if ($Path.Length -gt 0) { + if ($Path[$Path.Length - 1] -ne "\") { + $FullPath = $Path + "\" + $File + } + else { + $FullPath = $Path + $File + } + } + + return $FullPath +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/Menu.ps1 b/ATAPAuditor/Helpers/Menu.ps1 new file mode 100644 index 0000000..2558759 --- /dev/null +++ b/ATAPAuditor/Helpers/Menu.ps1 @@ -0,0 +1,142 @@ +# Get the report names from the files in the Module folder +function Get-Reports { + # Get the path to the module + $atapFile = (Get-Module -ListAvailable ATAPAuditor).Path + if ($atapFile.Count -gt 1) { + $atapFile = $atapFile[0] # use the first result if there are several + } elseif ($atapFile.Count -eq 0) { + Write-Host "The ATAP module could not be found." + pressAnyKeyToQuit + Exit + } + + # find all *.ps1 report files + $atapDir = Split-Path -parent $atapFile + $reportsDir = Join-Path -Path $atapDir -ChildPath "Reports" + $reportFiles = Get-ChildItem -Path "$reportsDir\*.ps1" -Recurse + + # Build a dictionary from the file names without the extension + $i = 1 + $reports = [ordered]@{} + foreach ($reportName in $reportFiles) { + $reports.add([string]$i, $reportName.BaseName) + $i++ + } + return $reports +} + +# present a menu based on the dict given as argument +function Show-Menu { + param ( + [System.Collections.Specialized.OrderedDictionary]$reports + ) + Clear-Host + Write-Host "============== AuditTAP Reports ==============`n" + $padCount = ([string]$reports.Count).Length + foreach ($item in $reports.GetEnumerator()) { + Write-Host (' {0}: {1}' -f $item.Key.PadLeft($padCount, ' '), $item.Value) + } + Write-Host "" +} + + +function askSelection { + param ( + [System.Collections.Specialized.OrderedDictionary]$reports + ) + $retry = $false + :loop while ($true) { + # show menu and ask the user for a selection (or multiple) + Show-Menu $reports + if ($retry) { + [string]$selection = Read-Host "Invalid selection. Please try again`nYou can select multiple reports by comma separating the numbers" + } else { + [string]$selection = Read-Host "Please choose a report to run`nYou can select multiple reports by comma separating the numbers" + } + + # sanitize input data + $selection = $selection -replace '\s','' + $selection = $selection.Trim(',') + $selectionArray = $selection.Split(",") + $selectionArray = $selectionArray | Select-Object -Unique + + # Check if requested reports are valid / actually present + $reportsValid = @() + foreach ($i in $selectionArray) { + if (!$reports.Contains($i)) { + Write-Host "Report $i does not exist" + $retry = $true + Continue loop + } else { + $reportsValid += $reports[$i] + } + } + + # return the list of valid reports as an array of strings + return $reportsValid + } +} + +function runReports { + param ( + [string[]]$report + ) + Clear-Host + Import-Module -Name ATAPAuditor -Force + foreach ($i in $report) { + Write-Host "Running report: $i" + Save-ATAPHtmlReport -ReportName $i -Force + Write-Host "" + } +} + +function isAdmin { + $unixOS = [System.Environment]::OSVersion.Platform -eq 'Unix' + if ($unixOS) { + return ($(id -u) -eq 0) + } else { + return ([Security.Principal.WindowsIdentity]::GetCurrent().Groups -contains 'S-1-5-32-544') + } +} + +function pressAnyKeyToQuit { + if ($psISE) { + Return + } + Write-Host "Press any key to quit" + $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown') +} + +if (!(isAdmin)) { + Write-Host "Please run as administrator`n" + pressAnyKeyToQuit +} else { + $reports = Get-Reports + Show-Menu $reports + $sel = askSelection $reports + runReports $sel + + if ([System.Environment]::OSVersion.Platform -eq 'Unix') { + if (($env:XDG_SESSION_TYPE -eq 'tty') -or ($null -eq $env:SUDO_USER)) { + # 1. reason to return: no graphical environment to open the file explorer + # 2. reason to return: we do not want to open the file explorer as root + Return + } + } + + [string]$action = Read-Host "Do you want to open the output directory? (Y/N)" + if ($action -eq 'y' -or $action -eq 'Y') { + if ($null -eq $env:ATAPReportPath) { + $outPath = [Environment]::GetFolderPath('MyDocuments') | Join-Path -ChildPath 'ATAPReports' + } else { + $outPath = $env:ATAPReportPath + } + if (Test-Path -Path $outPath) { + if ([System.Environment]::OSVersion.Platform -eq 'Unix') { + su $env:SUDO_USER -c "xdg-open $outPath" + } else { + explorer.exe $outPath + } + } + } +} diff --git a/ATAPAuditor/Helpers/ReportUnixOS.ps1 b/ATAPAuditor/Helpers/ReportUnixOS.ps1 new file mode 100644 index 0000000..f543045 --- /dev/null +++ b/ATAPAuditor/Helpers/ReportUnixOS.ps1 @@ -0,0 +1,20 @@ +[SystemInformation]@{ + SoftwareInformation = [SoftwareInformation]@{ + Hostname = hostname + OperatingSystem = (Get-Content /etc/os-release | Select-String -Pattern '^PRETTY_NAME=\"(.*)\"$').Matches.Groups[1].Value + BuildNumber = 'Version {0} (Build {1}.{2})' -f $v.DisplayVersion, $v.CurrentBuildNumber, $v.UBR + InstallationLanguage = (($(locale) | Where-Object { $_ -match "LANG=" }) -split '=')[1] + SystemUptime = uptime -p + OSArchitecture = lscpu | awk '/Architecture/ {print $2}' + KernelVersion = uname -r + } + HardwareInformation = [HardwareInformation]@{ + BIOSVersion = dmidecode -s bios-version + SystemSKU = (dmidecode -t system)[12] | cut -d ':' -f 2 | xargs + SystemSerialnumber = (dmidecode -t system)[9] | cut -d ':' -f 2 | xargs + SystemManufacturer = (dmidecode -t system)[6] | cut -d ':' -f 2 | xargs + SystemModel = dmidecode -s system-product-name + FreeDiskSpace = "{0:N1} GB" -f ((Get-PSDrive | Where-Object { $_.Name -eq '/' }).Free / 1GB) + FreePhysicalMemory = "{0:N1} GB" -f (( -split (Get-Content /proc/meminfo | Where-Object { $_ -match 'MemFree:' }))[1] / 1MB) + } +} diff --git a/ATAPAuditor/Helpers/ReportWindowsOS.ps1 b/ATAPAuditor/Helpers/ReportWindowsOS.ps1 new file mode 100644 index 0000000..515f7fd --- /dev/null +++ b/ATAPAuditor/Helpers/ReportWindowsOS.ps1 @@ -0,0 +1,41 @@ +$infos = Get-CimInstance Win32_OperatingSystem +$disk = Get-CimInstance Win32_LogicalDisk | Where-Object -Property DeviceID -eq "C:" +$role = Switch ((Get-CimInstance -Class Win32_ComputerSystem).DomainRole) { + "0" { "Standalone Workstation" } + "1" { "Member Workstation" } + "2" { "Standalone Server" } + "3" { "Member Server" } + "4" { "Backup Domain Controller" } + "5" { "Primary Domain Controller" } +} +$freeMemory = ($infos.FreePhysicalMemory / 1024) / 1024; +$totalMemory = ($infos.TotalVirtualMemorySize / 1024) / 1024; +$uptime = (get-date) - (gcim Win32_OperatingSystem).LastBootUpTime +$v = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' + + +[SystemInformation]@{ + SoftwareInformation = [SoftwareInformation]@{ + Hostname = hostname + DomainRole = $role + OperatingSystem = $infos.Caption + LicenseStatus = $lcStatus + BuildNumber = 'Version {0} (Build {1}.{2})' -f $v.DisplayVersion, $v.CurrentBuildNumber, $v.UBR + InstallationLanguage = ((Get-UICulture).DisplayName) + SystemUptime = '{0:d1}:{1:d2}:{2:d2}:{3:d2}' -f $uptime.Days, $uptime.Hours, $uptime.Minutes, $uptime.Seconds + OSArchitecture = (Get-WmiObject win32_operatingsystem | select osarchitecture).osarchitecture + } + HardwareInformation = [HardwareInformation]@{ + BIOSVersion = (Get-WmiObject -Class Win32_BIOS).Version + SystemSKU = (Get-WmiObject -Namespace root\wmi -Class MS_SystemInformation).SystemSKU + SystemSerialnumber = (Get-WmiObject win32_bios).Serialnumber + SystemManufacturer = (Get-WMIObject -class Win32_ComputerSystem).Manufacturer + SystemModel = (Get-WMIObject -class Win32_ComputerSystem).Model + FreeDiskSpace = "{0:N3}" -f "$([math]::Round(($disk.FreeSpace / $disk.Size)*100,1))% " + "{0:N3}" -f "($([math]::Round($disk.FreeSpace / 1GB,1)) GB / $([math]::Round($disk.Size / 1GB,1)) GB)" + FreePhysicalMemory = "{0:N3}" -f "$([math]::Round(($freeMemory/$totalMemory)*100,1))% ($([math]::Round($freeMemory,1)) GB / $([math]::Round($totalMemory,1)) GB)" + } +} + + + + diff --git a/ATAPAuditor/Helpers/SecurityPolicy.psm1 b/ATAPAuditor/Helpers/SecurityPolicy.psm1 new file mode 100644 index 0000000..5a3b787 --- /dev/null +++ b/ATAPAuditor/Helpers/SecurityPolicy.psm1 @@ -0,0 +1,36 @@ +function ConvertTo-NTAccountUser { + [CmdletBinding()] + [OutputType([hashtable])] + Param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string] $Name + ) + + process { + try { + # Identity doesn't exist on when Hyper-V isn't installed + if ($Name -eq "NT VIRTUAL MACHINE\Virtual Machines" -and + (Get-WindowsOptionalFeature -Online -FeatureName "Microsoft-Hyper-V").State -ne "Enabled") { + return $null + } + + Write-Verbose "[ConvertTo-NTAccountUser] Converting identity '$Name' to NTAccount" + if ($Name -match "^(S-[0-9-]{3,})") { + $sidAccount = [System.Security.Principal.SecurityIdentifier]$Name + } + else { + $sidAccount = ([System.Security.Principal.NTAccount]$Name).Translate([System.Security.Principal.SecurityIdentifier]) + } + return @{ + Account = $sidAccount.Translate([System.Security.Principal.NTAccount]) + Sid = $sidAccount.Value + } + } + catch{ + return @{ + Account = "Orphaned Account" + Sid = $Name + } + } + } +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.1.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.1.sh new file mode 100644 index 0000000..1ee773e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.1.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_mname="cramfs" # set module name + # Check how module will be loaded + l_loadable="$(modprobe -n -v "$l_mname")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + # Check is the module currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + # Check if the module is deny listed + if grep -Pq -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: + \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + # Report results. If no failures output in l_output2, we pass + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.2.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.2.sh new file mode 100644 index 0000000..d3b73f2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.2.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_mname="squashfs" # set module name + # Check how module will be loaded + l_loadable="$(modprobe -n -v "$l_mname")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + # Check is the module currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + # Check if the module is deny listed + if grep -Pq -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + # Report results. If no failures output in l_output2, we pass + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.3.sh new file mode 100644 index 0000000..18d958f --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.1.3.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_mname="udf" # set module name + # Check how module will be loaded + l_loadable="$(modprobe -n -v "$l_mname")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + # Check is the module currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + # Check if the module is deny listed + if grep -Pq -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + # Report results. If no failures output in l_output2, we pass + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.10.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.10.sh new file mode 100644 index 0000000..aa407a1 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.1.10.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_mname="usb-storage" # set module name + # Check how module will be loaded + l_loadable="$(modprobe -n -v "$l_mname")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: +\"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: +\"$l_loadable\"" + fi + # Check is the module currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + # Check if the module is deny listed + if grep -Pq -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: +\"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + # Report results. If no failures output in l_output2, we pass + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit +failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.5.1.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.5.1.sh new file mode 100644 index 0000000..b6121b8 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.5.1.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="kernel.randomize_va_space" + kpvalue="2" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc )" + fafile="$( grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}' )" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " + [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.2.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.2.sh new file mode 100644 index 0000000..a031d2c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.2.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" # Space seporated list of packages to check + for l_pn in $l_pcl; do + $l_pq "$l_pn" >/dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - +Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + echo -e "$l_pkgoutput" + # Look for existing settings and set variables if they exist + l_gdmfile="$( + grep -Prils '^\h*banner-message-enable\b' + /etc/dconf/db/*.d + )" + if [ -n "$l_gdmfile" ]; then + # Set profile name based on dconf db directory ({PROFILE_NAME}.d) + l_gdmprofile="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<<"$l_gdmfile")" + # Check if banner message is enabled + if grep -Pisq '^\h*banner-message-enable=true\b' "$l_gdmfile"; then + l_output="$l_output\n - The \"banner-message-enable\" option is +enabled in \"$l_gdmfile\"" + else + l_output2="$l_output2\n - The \"banner-message-enable\" option is +not enabled" + fi + l_lsbt="$(grep -Pios '^\h*banner-message-text=.*$' "$l_gdmfile")" + if [ -n "$l_lsbt" ]; then + l_output="$l_output\n - The \"banner-message-text\" option is set +in \"$l_gdmfile\"\n - banner-message-text is set to:\n - \"$l_lsbt\"" + else + l_output2="$l_output2\n - The \"banner-message-text\" option is +not set" + fi + if + grep -Pq "^\h*system-db:$l_gdmprofile" + /etc/dconf/profile/"$l_gdmprofile" + then + l_output="$l_output\n - The \"$l_gdmprofile\" profile exists" + else + l_output2="$l_output2\n - The \"$l_gdmprofile\" profile doesn't +exist" + fi + if [ -f "/etc/dconf/db/$l_gdmprofile" ]; then + l_output="$l_output\n - The \"$l_gdmprofile\" profile exists in +the dconf database" + else + l_output2="$l_output2\n - The \"$l_gdmprofile\" profile doesn't +exist in the dconf database" + fi + else + l_output2="$l_output2\n - The \"banner-message-enable\" option isn't +configured" + fi + else + echo -e "\n\n - GNOME Desktop Manager isn't installed\n - +Recommendation is Not Applicable\n- Audit result:\n *** PASS ***\n" + fi + # Report results. If no failures output in l_output2, we pass + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit +failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.3.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.3.sh new file mode 100644 index 0000000..c4e7589 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.3.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" # Space seporated list of packages to check + for l_pn in $l_pcl; do + $l_pq "$l_pn" >/dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n -Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + output="" output2="" + l_gdmfile="$(grep -Pril '^\h*disable-user-list\h*=\h*true\b' /etc/dconf/db )" + if [ -n "$l_gdmfile" ]; then + output="$output\n - The \"disable-user-list\" option is enabled in \"$l_gdmfile\"" + l_gdmprofile="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<<"$l_gdmfile")" + if + grep -Pq "^\h*system-db:$l_gdmprofile" /etc/dconf/profile/"$l_gdmprofile" + then + output="$output\n - The \"$l_gdmprofile\" exists" + else + output2="$output2\n - The \"$l_gdmprofile\" doesn't exist" + fi + if [ -f "/etc/dconf/db/$l_gdmprofile" ]; then + output="$output\n - The \"$l_gdmprofile\" profile exists in the dconf database" + else + output2="$output2\n - The \"$l_gdmprofile\" profile doesn't exist in the dconf database" + fi + else + output2="$output2\n - The \"disable-user-list\" option is not enabled" + fi + if [ -z "$output2" ]; then + echo -e "$l_pkgoutput\n- Audit result:\n *** PASS: ***\n$output\n" + else + echo -e "$l_pkgoutput\n- Audit Result:\n *** FAIL: ***\n$output2\n" + [ -n "$output" ] && echo -e "$output\n" + fi + else + echo -e "\n\n - GNOME Desktop Manager isn't installed\n - Recommendation is Not Applicable\n- Audit result:\n *** PASS ***\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.4.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.4.sh new file mode 100644 index 0000000..8d711a9 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.4.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +{ + # Check if GNMOE Desktop Manager is installed. If package isn't installed, recommendation is Not Applicable\n + # determine system's package manager + l_pkgoutput="" + if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" + fi + # Check if GDM is installed + l_pcl="gdm gdm3" # Space seporated list of packages to check + for l_pn in $l_pcl; do + $l_pq "$l_pn" >/dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n -Package: \"$l_pn\" exists on the system\n - checking configuration" + done + # Check configuration (If applicable) + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + l_idmv="900" # Set for max value for idle-delay in seconds + l_ldmv="5" # Set for max value for lock-delay in seconds + # Look for idle-delay to determine profile in use, needed for remaining tests + l_kfile="$(grep -Psril '^\h*idle-delay\h*=\h*uint32\h+\d+\b' /etc/dconf/db/*/ )" # Determine file containing idle-delay key + if [ -n "$l_kfile" ]; then + # set profile name (This is the name of a dconf database) + l_profile="$(awk -F'/' '{split($(NF-1),a,".");print a[1]}' <<<"$l_kfile")" #Set the key profile name + l_pdbdir="/etc/dconf/db/$l_profile.d" # Set the key file dconf db directory + # Confirm that idle-delay exists, includes unit32, and value is between 1 and max value for idle-delay + l_idv="$(awk -F 'uint32' '/idle-delay/{print $2}' "$l_kfile" | xargs)" + if [ -n "$l_idv" ]; then + [ "$l_idv" -gt "0" -a "$l_idv" -le "$l_idmv" ] && l_output="$l_output\n - The \"idle-delay\" option is set to \"$l_idv\" seconds in \"$l_kfile\"" + [ "$l_idv" = "0" ] && l_output2="$l_output2\n - The \"idle-delay\" option is set to \"$l_idv\" (disabled) in \"$l_kfile\"" + [ "$l_idv" -gt "$l_idmv" ] && l_output2="$l_output2\n - The \"idle-delay\" option is set to \"$l_idv\" seconds (greater than $l_idmv) in \"$l_kfile\"" + else + l_output2="$l_output2\n - The \"idle-delay\" option is not set in \"$l_kfile\"" + fi + # Confirm that lock-delay exists, includes unit32, and value is between 0 and max value for lock-delay + l_ldv="$(awk -F 'uint32' '/lock-delay/{print $2}' "$l_kfile" |xargs)" + if [ -n "$l_ldv" ]; then + [ "$l_ldv" -ge "0" -a "$l_ldv" -le "$l_ldmv" ] && l_output="$l_output\n - The \"lock-delay\" option is set to \"$l_ldv\" seconds in \"$l_kfile\"" + [ "$l_ldv" -gt "$l_ldmv" ] && l_output2="$l_output2\n - The \"lock-delay\" option is set to \"$l_ldv\" seconds (greater than $l_ldmv) in \"$l_kfile\"" + else + l_output2="$l_output2\n - The \"lock-delay\" option is not set in \"$l_kfile\"" + fi + # Confirm that dconf profile exists + if grep -Psq "^\h*system-db:$l_profile" /etc/dconf/profile/*; then + l_output="$l_output\n - The \"$l_profile\" profile exists" + else + l_output2="$l_output2\n - The \"$l_profile\" doesn't exist" + fi + # Confirm that dconf profile database file exists + if [ -f "/etc/dconf/db/$l_profile" ]; then + l_output="$l_output\n - The \"$l_profile\" profile exists in the dconf database" + else + l_output2="$l_output2\n - The \"$l_profile\" profile doesn't exist in the dconf database" + fi + else + l_output2="$l_output2\n - The \"idle-delay\" option doesn't exist, remaining tests skipped" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + # Report results. If no failures output in l_output2, we pass + [ -n "$l_pkgoutput" ] && echo -e "\n$l_pkgoutput" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.5.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.5.sh new file mode 100644 index 0000000..3581400 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.5.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +{ + # Check if GNOME Desktop Manager is installed. If package isn't installed, recommendation is Not Applicable\n + # determine system's package manager + l_pkgoutput="" + if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" + fi + # Check if GDM is installed + l_pcl="gdm gdm3" # Space seporated list of packages to check + for l_pn in $l_pcl; do + $l_pq "$l_pn" >/dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n -Package: \"$l_pn\" exists on the system\n - checking configuration" + done + # Check configuration (If applicable) + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + # Look for idle-delay to determine profile in use, needed for remaining tests + l_kfd="/etc/dconf/db/$(grep -Psril '^\h*idle-delay\h*=\h*uint32\h+\d+\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" #set directory of key file to be locked + l_kfd2="/etc/dconf/db/$(grep -Psril '^\h*lock-delay\h*=\h*uint32\h+\d+\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" #set directory of key file to be locked + if [ -d "$l_kfd" ]; then # If key file directory doesn't exist, options can't be locked + if + grep -Prilq '\/org\/gnome\/desktop\/session\/idle-delay\b' + "$l_kfd" + then + l_output="$l_output\n - \"idle-delay\" is locked in \"$( + grep -Pril '\/org\/gnome\/desktop\/session\/idle-delay\b' "$l_kfd" + )\"" + else + l_output2="$l_output2\n - \"idle-delay\" is not locked" + fi + else + l_output2="$l_output2\n - \"idle-delay\" is not set so it can not be locked" + fi + if [ -d "$l_kfd2" ]; then # If key file directory doesn't exist, options can't be locked + if + grep -Prilq '\/org\/gnome\/desktop\/screensaver\/lock-delay\b' + "$l_kfd2" + then + l_output="$l_output\n - \"lock-delay\" is locked in \"$( + grep - + Pril '\/org\/gnome\/desktop\/screensaver\/lock-delay\b' "$l_kfd2" + )\"" + else + l_output2="$l_output2\n - \"lock-delay\" is not locked" + fi + else + l_output2="$l_output2\n - \"lock-delay\" is not set so it can not be +locked" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed +on the system\n - Recommendation is not applicable" + fi + # Report results. If no failures output in l_output2, we pass + [ -n "$l_pkgoutput" ] && echo -e "\n$l_pkgoutput" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit +failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.6.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.6.sh new file mode 100644 index 0000000..7632b13 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.6.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" l_output="" l_output2="" + # Check if GNOME Desktop Manager is installed. If package isn't installed, recommendation is Not Applicable\n + # determine system's package manager + if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" + fi + # Check if GDM is installed + l_pcl="gdm gdm3" # Space seporated list of packages to check + for l_pn in $l_pcl; do + $l_pq "$l_pn" >/dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n -Package: \"$l_pn\" exists on the system\n - checking configuration" + done + # Check configuration (If applicable) + if [ -n "$l_pkgoutput" ]; then + echo -e "$l_pkgoutput" + # Look for existing settings and set variables if they exist + l_kfile="$(grep -Prils -- '^\h*automount\b' /etc/dconf/db/*.d)" + l_kfile2="$(grep -Prils -- '^\h*automount-open\b' /etc/dconf/db/*.d)" + # Set profile name based on dconf db directory ({PROFILE_NAME}.d) + if [ -f "$l_kfile" ]; then + l_gpname="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<<"$l_kfile")" + elif [ -f "$l_kfile2" ]; then + l_gpname="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<<"$l_kfile2")" + fi + # If the profile name exist, continue checks + if [ -n "$l_gpname" ]; then + l_gpdir="/etc/dconf/db/$l_gpname.d" + # Check if profile file exists + if grep -Pq -- "^\h*system-db:$l_gpname\b" /etc/dconf/profile/*; then + l_output="$l_output\n - dconf database profile file \"$(grep -Pl -- "^\h*system-db:$l_gpname\b" /etc/dconf/profile/*)\" exists" + else + l_output2="$l_output2\n - dconf database profile isn't set" + fi + # Check if the dconf database file exists + if [ -f "/etc/dconf/db/$l_gpname" ]; then + l_output="$l_output\n - The dconf database \"$l_gpname\" exists" + else + l_output2="$l_output2\n - The dconf database \"$l_gpname\" doesn't exist" + fi + # check if the dconf database directory exists + if [ -d "$l_gpdir" ]; then + l_output="$l_output\n - The dconf directory \"$l_gpdir\" exitst" + else + l_output2="$l_output2\n - The dconf directory \"$l_gpdir\" doesn't exist" + fi + # check automount setting + if grep -Pqrs -- '^\h*automount\h*=\h*false\b' "$l_kfile"; then + l_output="$l_output\n - \"automount\" is set to false in: \"$l_kfile\"" + else + l_output2="$l_output2\n - \"automount\" is not set correctly" + fi + # check automount-open setting + if grep -Pqs -- '^\h*automount-open\h*=\h*false\b' "$l_kfile2"; then + l_output="$l_output\n - \"automount-open\" is set to false in: \"$l_kfile2\"" + else + l_output2="$l_output2\n - \"automount-open\" is not set correctly" + fi + else + # Setings don't exist. Nothing further to check + l_output2="$l_output2\n - neither \"automount\" or \"automount-open\" is set" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + # Report results. If no failures output in l_output2, we pass + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.7.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.7.sh new file mode 100644 index 0000000..b0ec907 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.7.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +{ + # Check if GNOME Desktop Manager is installed. If package isn't installed, recommendation is Not Applicable\n + # determine system's package manager + l_pkgoutput="" + if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" + fi + # Check if GDM is installed + l_pcl="gdm gdm3" # Space seporated list of packages to check + for l_pn in $l_pcl; do + $l_pq "$l_pn" >/dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n -Package: \"$l_pn\" exists on the system\n - checking configuration" + done + # Check configuration (If applicable) + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + # Look for idle-delay to determine profile in use, needed for remaining tests + l_kfd="/etc/dconf/db/$(grep -Psril '^\h*automount\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" #set directory of key file to be locked + l_kfd2="/etc/dconf/db/$(grep -Psril '^\h*automount-open\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}' ).d" #set directory of key file to be locked + if [ -d "$l_kfd" ]; then # If key file directory doesn't exist, options can't be locked + if + grep -Piq '^\h*\/org/gnome\/desktop\/media-handling\/automount\b' + "$l_kfd" + then + l_output="$l_output\n - \"automount\" is locked in \"$( + grep -Pil + '^\h*\/org/gnome\/desktop\/media-handling\/automount\b' "$l_kfd" + )\"" + else + l_output2="$l_output2\n - \"automount\" is not locked" + fi + else + l_output2="$l_output2\n - \"automount\" is not set so it can not be +locked" + fi + if [ -d "$l_kfd2" ]; then # If key file directory doesn't exist, options can't be locked + if grep -Piq '^\h*\/org/gnome\/desktop\/media-handling\/automount- +open\b' "$l_kfd2"; then + l_output="$l_output\n - \"lautomount-open\" is locked in \"$( + grep + -Pril '^\h*\/org/gnome\/desktop\/media-handling\/automount-open\b' "$l_kfd2" + )\"" + else + l_output2="$l_output2\n - \"automount-open\" is not locked" + fi + else + l_output2="$l_output2\n - \"automount-open\" is not set so it can +not be locked" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed +on the system\n - Recommendation is not applicable" + fi + # Report results. If no failures output in l_output2, we pass + [ -n "$l_pkgoutput" ] && echo -e "\n$l_pkgoutput" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit +failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.8.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.8.sh new file mode 100644 index 0000000..4fdd471 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.8.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" l_output="" l_output2="" + # Check if GNOME Desktop Manager is installed. If package isn't installed, recommendation is Not Applicable\n + # determine system's package manager + if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" + fi + # Check if GDM is installed + l_pcl="gdm gdm3" # Space separated list of packages to check + for l_pn in $l_pcl; do + $l_pq "$l_pn" >/dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - +Package: \"$l_pn\" exists on the system\n - checking configuration" + echo -e "$l_pkgoutput" + done + # Check configuration (If applicable) + if [ -n "$l_pkgoutput" ]; then + echo -e "$l_pkgoutput" + # Look for existing settings and set variables if they exist + l_kfile="$(grep -Prils -- '^\h*autorun-never\b' /etc/dconf/db/*.d)" + # Set profile name based on dconf db directory ({PROFILE_NAME}.d) + if [ -f "$l_kfile" ]; then + l_gpname="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<<"$l_kfile")" + fi + # If the profile name exist, continue checks + if [ -n "$l_gpname" ]; then + l_gpdir="/etc/dconf/db/$l_gpname.d" + # Check if profile file exists + if grep -Pq -- "^\h*system-db:$l_gpname\b" /etc/dconf/profile/*; then + l_output="$l_output\n - dconf database profile file \"$( + grep -Pl + -- "^\h*system-db:$l_gpname\b" /etc/dconf/profile/* + )\" exists" + else + l_output2="$l_output2\n - dconf database profile isn't set" + fi + # Check if the dconf database file exists + if [ -f "/etc/dconf/db/$l_gpname" ]; then + l_output="$l_output\n - The dconf database \"$l_gpname\" exists" + else + l_output2="$l_output2\n - The dconf database \"$l_gpname\" +doesn't exist" + fi + # check if the dconf database directory exists + if [ -d "$l_gpdir" ]; then + l_output="$l_output\n - The dconf directory \"$l_gpdir\" exitst" + else + l_output2="$l_output2\n - The dconf directory \"$l_gpdir\" +doesn't exist" + fi + # check autorun-never setting + if grep -Pqrs -- '^\h*autorun-never\h*=\h*true\b' "$l_kfile"; then + l_output="$l_output\n - \"autorun-never\" is set to true in: +\"$l_kfile\"" + else + l_output2="$l_output2\n - \"autorun-never\" is not set correctly" + fi + else + # Settings don't exist. Nothing further to check + l_output2="$l_output2\n - \"autorun-never\" is not set" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed +on the system\n - Recommendation is not applicable" + fi + # Report results. If no failures output in l_output2, we pass + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit +failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.9.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.9.sh new file mode 100644 index 0000000..030120a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-1.8.9.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +{ + # Check if GNOME Desktop Manager is installed. If package isn't installed, recommendation is Not Applicable\n + # determine system's package manager + l_pkgoutput="" + if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" + fi + # Check if GDM is installed + l_pcl="gdm gdm3" # Space separated list of packages to check + for l_pn in $l_pcl; do + $l_pq "$l_pn" >/dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n -Package: \"$l_pn\" exists on the system\n - checking configuration" + done + # Check configuration (If applicable) + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + # Look for idle-delay to determine profile in use, needed for remaining tests + l_kfd="/etc/dconf/db/$( grep -Psril '^\h*autorun-never\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" #set directory of key file to be locked + if [ -d "$l_kfd" ]; then # If key file directory doesn't exist, options can't be locked + if grep -Piq '^\h*\/org/gnome\/desktop\/media-handling\/autorun-never\b' "$l_kfd"; then + l_output="$l_output\n - \"autorun-never\" is locked in \"$( + grep -Pil '^\h*\/org/gnome\/desktop\/media-handling\/autorun-never\b' "$l_kfd" + )\"" + else + l_output2="$l_output2\n - \"autorun-never\" is not locked" + fi + else + l_output2="$l_output2\n - \"autorun-never\" is not set so it can not be locked" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + # Report results. If no failures output in l_output2, we pass + [ -n "$l_pkgoutput" ] && echo -e "\n$l_pkgoutput" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-2.1.1.1.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-2.1.1.1.sh new file mode 100644 index 0000000..02ca1a6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-2.1.1.1.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +{ + output="" l_tsd="" l_sdtd="" chrony="" l_ntp="" + dpkg-query -W chrony >/dev/null 2>&1 && l_chrony="y" + dpkg-query -W ntp >/dev/null 2>&1 && l_ntp="y" || l_ntp="" + systemctl list-units --all --type=service | grep -q 'systemd- +timesyncd.service' && systemctl is-enabled systemd-timesyncd.service | grep -q 'enabled' && l_sdtd="y" + # ! systemctl is-enabled systemd-timesyncd.service | grep -q 'enabled' && + l_nsdtd="y" || l_nsdtd="" + if [[ "$l_chrony" = "y" && "$l_ntp" != "y" && "$l_sdtd" != "y" ]]; then + l_tsd="chrony" + output="$output\n- chrony is in use on the system" + elif [[ "$l_chrony" != "y" && "$l_ntp" = "y" && "$l_sdtd" != "y" ]]; then + l_tsd="ntp" + output="$output\n- ntp is in use on the system" + elif [[ "$l_chrony" != "y" && "$l_ntp" != "y" ]]; then + if + systemctl list-units --all --type=service | grep -q 'systemd- +timesyncd.service' && systemctl is-enabled systemd-timesyncd.service | grep -Eq '(enabled|disabled|masked)' + then + l_tsd="sdtd" + output="$output\n- systemd-timesyncd is in use on the system" + fi + else + [[ "$l_chrony" = "y" && "$l_ntp" = "y" ]] && output="$output\n- both +chrony and ntp are in use on the system" + [[ "$l_chrony" = "y" && "$l_sdtd" = "y" ]] && output="$output\n- both +chrony and systemd-timesyncd are in use on the system" + [[ "$l_ntp" = "y" && "$l_sdtd" = "y" ]] && output="$output\n- both ntp +and systemd-timesyncd are in use on the system" + fi + if [ -n "$l_tsd" ]; then + echo -e "\n- PASS:\n$output\n" + else + echo -e "\n- FAIL:\n$output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.1.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.1.sh new file mode 100644 index 0000000..69033ff --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.1.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +{ + output="" + grubfile=$(find /boot -type f \( -name 'grubenv' -o -name 'grub.conf' -o -name 'grub.cfg' \) -exec grep -Pl -- '^\h*(kernelopts=|linux|kernel)' {} \; ) + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + if [ -s "$grubfile" ]; then + ! grep -P -- "^\h*(kernelopts=|linux|kernel)" "$grubfile" | grep -vq -- ipv6.disable=1 && output="IPv6 Disabled in \"$grubfile\"" + fi + if + grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\h*(#.*)?$" $searchloc && grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\h*(#.*)?$" $searchloc && sysctl net.ipv6.conf.all.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\h*(#.*)?$" && sysctl net.ipv6.conf.default.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\h*(#.*)?$" + then + [ -n "$output" ] && output="$output, and in sysctl config" || output="ipv6 disabled in sysctl config" + fi + [ -n "$output" ] && echo -e "\n$output\n" || echo -e "\nIPv6 is enabled on the system\n" +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.2.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.2.sh new file mode 100644 index 0000000..725bc7a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.2.sh @@ -0,0 +1,29 @@ +#!/bin/bash +if command -v nmcli >/dev/null 2>&1; then + if nmcli radio all | grep -Eq '\s*\S+\s+disabled\s+\S+\s+disabled\b'; then + echo "Wireless is not enabled" + else + nmcli radio all + fi +elif [ -n "$(find /sys/class/net/*/ -type d -name wireless)" ]; then + t=0 + mname=$(for driverdir in $(find /sys/class/net/*/ -type d -name wireless | + xargs -0 dirname); do basename "$( + readlink -f + "$driverdir"/device/driver/module + )"; done | sort -u) + for dm in $mname; do + if + grep -Eq "^\s*install\s+$dm\s+/bin/(true|false)" + /etc/modprobe.d/*.conf + then + /bin/true + else + echo "$dm is not disabled" + t=1 + fi + done + [ "$t" -eq 0 ] && echo "Wireless is not enabled" +else + echo "Wireless is not enabled" +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.3.sh new file mode 100644 index 0000000..ce129a5 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.3.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_mname="dccp" # set module name + # Check if the module exists on the system + if + [ -z "$(modprobe -n -v "$l_mname" 2>&1 | grep -Pi -- "\h*modprobe:\h+FATAL:\h+Module\h+$l_mname\h+not\h+found\h+in\h+directory")" ] + then + # Check how module will be loaded + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$( + grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable" )" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + # Check is the module currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + # Check if the module is deny listed + if modprobe --showconfig | grep -Pq -- "^\h*blacklist\h+$(tr '-' '_' <<<"$l_mname" )\b"; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + else + l_output="$l_output\n - Module \"$l_mname\" doesn't exist on the system" + fi + # Report results. If no failures output in l_output2, we pass + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.4.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.4.sh new file mode 100644 index 0000000..824c81c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.4.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_mname="sctp" # set module name + # Check if the module exists on the system + if + [ -z "$(modprobe -n -v "$l_mname" 2>&1 | grep -Pi -- "\h*modprobe:\h+FATAL:\h+Module\h+$l_mname\h+not\h+found\h+in\h+directory" )" ] + then + # Check how module will be loaded + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$( grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable" )" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + # Check is the module currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + # Check if the module is deny listed + if modprobe --showconfig | grep -Pq -- "^\h*blacklist\h+$l_mname\b"; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + else + l_output="$l_output\n - Module \"$l_mname\" doesn't exist on the system" + fi + # Report results. If no failures output in l_output2, we pass + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.5.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.5.sh new file mode 100644 index 0000000..715a2a2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.5.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_mname="rds" # set module name + # Check if the module exists on the system + if + [ -z "$(modprobe -n -v "$l_mname" 2>&1 | grep -Pi -- "\h*modprobe:\h+FATAL:\h+Module\h+$l_mname\h+not\h+found\h+in\h+directory" )" ] + then + # Check how module will be loaded + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$( + grep -P -- + "(^\h*install|\b$l_mname)\b" <<<"$l_loadable" + )" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + # Check is the module currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + # Check if the module is deny listed + if modprobe --showconfig | grep -Pq -- "^\h*blacklist\h+$l_mname\b"; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + else + l_output="$l_output\n - Module \"$l_mname\" doesn't exist on the system" + fi + # Report results. If no failures output in l_output2, we pass + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.6.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.6.sh new file mode 100644 index 0000000..69aa653 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.1.6.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_mname="tipc" # set module name + # Check if the module exists on the system + if + [ -z "$(modprobe -n -v "$l_mname" 2>&1 | grep -Pi -- "\h*modprobe:\h+FATAL:\h+Module\h+$l_mname\h+not\h+found\h+in\h+directory")" ] + then + # Check how module will be loaded + l_loadable="$(modprobe -n -v "$l_mname")" [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable" )" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + # Check is the module currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + # Check if the module is deny listed + if modprobe --showconfig | grep -Pq -- "^\h*blacklist\h+$l_mname\b"; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + else + l_output="$l_output\n - Module \"$l_mname\" doesn't exist on the system" + fi + # Report results. If no failures output in l_output2, we pass + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.2.1.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.2.1.sh new file mode 100644 index 0000000..2e5b79b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.2.1.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_parlist="net.ipv4.conf.all.send_redirects=0 net.ipv4.conf.default.send_redirects=0" + l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/{print $2}' /etc/default/ufw)" + KPC() { + l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)" + l_pafile="$(grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc )" + l_fafile="$(grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}' )" + if [ "$l_krp" = "$l_kpvalue" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration" + else + l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration" + fi + if [ -n "$l_pafile" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\"" + else + l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file" + fi + [ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\"" + } + for l_kpe in $l_parlist; do + l_kpname="$(awk -F= '{print $1}' <<<"$l_kpe")" + l_kpvalue="$(awk -F= '{print $2}' <<<"$l_kpe")" + KPC + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.2.2.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.2.2.sh new file mode 100644 index 0000000..9014aa3 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.2.2.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_parlist="net.ipv4.ip_forward=0 net.ipv6.conf.all.forwarding=0" + l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)" + KPC() { + l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)" + l_pafile="$(grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc)" + l_fafile="$(grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}' )" + if [ "$l_krp" = "$l_kpvalue" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration" + else + l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration" + fi + if [ -n "$l_pafile" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\"" + else + l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file" + fi + [ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\"" + } + ipv6_chk() { + l_ipv6s="" + grubfile=$(find /boot -type f \( -name 'grubenv' -o -name 'grub.conf' -o -name 'grub.cfg' \) -exec grep -Pl -- '^\h*(kernelopts=|linux|kernel)' {} \; ) + if [ -s "$grubfile" ]; then + ! grep -P -- "^\h*(kernelopts=|linux|kernel)" "$grubfile" | grep -vq -- ipv6.disable=1 && l_ipv6s="disabled" + fi + if + grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\h*(#.*)?$" $l_searchloc && grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\h*(#.*)?$" $l_searchloc && sysctl net.ipv6.conf.all.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\h*(#.*)?$" && sysctl net.ipv6.conf.default.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\h*(#.*)?$" + then + l_ipv6s="disabled" + fi + if [ -n "$l_ipv6s" ]; then + l_output="$l_output\n - IPv6 is disabled on the system, \"$l_kpname\" is not applicable" + else + KPC + fi + } + for l_kpe in $l_parlist; do + l_kpname="$(awk -F= '{print $1}' <<<"$l_kpe")" + l_kpvalue="$(awk -F= '{print $2}' <<<"$l_kpe")" + if grep -q '^net.ipv6.' <<<"$l_kpe"; then + ipv6_chk + else + KPC + fi + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.1.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.1.sh new file mode 100644 index 0000000..bd038a7 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.1.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_parlist="net.ipv4.conf.all.accept_source_route=0 net.ipv4.conf.default.accept_source_route=0 net.ipv6.conf.all.accept_source_route=0 net.ipv6.conf.default.accept_source_route=0" + l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)" + KPC() { + l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)" + l_pafile="$(grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc )" + l_fafile="$(grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}' )" + if [ "$l_krp" = "$l_kpvalue" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration" + else + l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration" + fi + if [ -n "$l_pafile" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\"" + else + l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file" + fi + [ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\"" + } + ipv6_chk() { + l_ipv6s="" + grubfile=$( + find /boot -type f \( -name 'grubenv' -o -name 'grub.conf' -o -name 'grub.cfg' \) -exec grep -Pl -- '^\h*(kernelopts=|linux|kernel)' {} \; + ) + if [ -s "$grubfile" ]; then + ! grep -P -- "^\h*(kernelopts=|linux|kernel)" "$grubfile" | grep -vq -- ipv6.disable=1 && l_ipv6s="disabled" + fi + if + grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\h*(#.*)?$" $l_searchloc && grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\h*(#.*)?$" $l_searchloc && sysctl net.ipv6.conf.all.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\h*(#.*)?$" && sysctl net.ipv6.conf.default.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\h*(#.*)?$" + then + l_ipv6s="disabled" + fi + if [ -n "$l_ipv6s" ]; then + l_output="$l_output\n - IPv6 is disabled on the system, \"$l_kpname\" is not applicable" + else + KPC + fi + } + for l_kpe in $l_parlist; do + l_kpname="$(awk -F= '{print $1}' <<<"$l_kpe")" + l_kpvalue="$(awk -F= '{print $2}' <<<"$l_kpe")" + if grep -q '^net.ipv6.' <<<"$l_kpe"; then + ipv6_chk + else + KPC + fi + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.2.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.2.sh new file mode 100644 index 0000000..24a149c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.2.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_parlist="net.ipv4.conf.all.accept_redirects=0 net.ipv4.conf.default.accept_redirects=0 net.ipv6.conf.all.accept_redirects=0 net.ipv6.conf.default.accept_redirects=0" + l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)" + KPC() { + l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)" + l_pafile="$(grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc )" + l_fafile="$(grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}' )" + if [ "$l_krp" = "$l_kpvalue" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration" + else + l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration" + fi + if [ -n "$l_pafile" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\"" + else + l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file" + fi + [ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\"" + } + ipv6_chk() { + l_ipv6s="" + grubfile=$( + find /boot -type f \( -name 'grubenv' -o -name 'grub.conf' -o -name 'grub.cfg' \) -exec grep -Pl -- '^\h*(kernelopts=|linux|kernel)' {} \; + ) + if [ -s "$grubfile" ]; then + ! grep -P -- "^\h*(kernelopts=|linux|kernel)" "$grubfile" | grep -vq -- ipv6.disable=1 && l_ipv6s="disabled" + fi + if + grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\h*(#.*)?$" $l_searchloc && grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\h*(#.*)?$" $l_searchloc && sysctl net.ipv6.conf.all.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\h*(#.*)?$" && sysctl net.ipv6.conf.default.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\h*(#.*)?$" + then + l_ipv6s="disabled" + fi + if [ -n "$l_ipv6s" ]; then + l_output="$l_output\n - IPv6 is disabled on the system, \"$l_kpname\" is not applicable" + else + KPC + fi + } + for l_kpe in $l_parlist; do + l_kpname="$(awk -F= '{print $1}' <<<"$l_kpe")" + l_kpvalue="$(awk -F= '{print $2}' <<<"$l_kpe")" + if grep -q '^net.ipv6.' <<<"$l_kpe"; then + ipv6_chk + else + KPC + fi + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.3.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.3.sh new file mode 100644 index 0000000..6e77404 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.3.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_parlist="net.ipv4.conf.default.secure_redirects=0 net.ipv4.conf.all.secure_redirects=0" + l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)" + KPC() { + l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)" + l_pafile="$(grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc )" + l_fafile="$( + grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}' + )" + if [ "$l_krp" = "$l_kpvalue" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration" + else + l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration" + fi + if [ -n "$l_pafile" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\"" + else + l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file" + fi + [ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\"" + } + for l_kpe in $l_parlist; do + l_kpname="$(awk -F= '{print $1}' <<<"$l_kpe")" + l_kpvalue="$(awk -F= '{print $2}' <<<"$l_kpe")" + KPC + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.4.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.4.sh new file mode 100644 index 0000000..48faa27 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.4.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_parlist="net.ipv4.conf.all.log_martians=1 net.ipv4.conf.default.log_martians=1" + l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)" + KPC() { + l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)" + l_pafile="$( + grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc + )" + l_fafile="$(grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}' )" + if [ "$l_krp" = "$l_kpvalue" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration" + else + l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration" + fi + if [ -n "$l_pafile" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\"" + else + l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file" + fi + [ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\"" + } + for l_kpe in $l_parlist; do + l_kpname="$(awk -F= '{print $1}' <<<"$l_kpe")" + l_kpvalue="$(awk -F= '{print $2}' <<<"$l_kpe")" + KPC + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.5.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.5.sh new file mode 100644 index 0000000..8f1d931 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.5.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_parlist="net.ipv4.icmp_echo_ignore_broadcasts=1" + l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)" + KPC() { + l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)" + l_pafile="$( grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc )" + l_fafile="$( + grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}' )" + if [ "$l_krp" = "$l_kpvalue" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration" + else + l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration" + fi + if [ -n "$l_pafile" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\"" + else + l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file" + fi + [ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\"" + } + for l_kpe in $l_parlist; do + l_kpname="$(awk -F= '{print $1}' <<<"$l_kpe")" + l_kpvalue="$(awk -F= '{print $2}' <<<"$l_kpe")" + KPC + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.6.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.6.sh new file mode 100644 index 0000000..cc54061 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.6.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_parlist="net.ipv4.icmp_ignore_bogus_error_responses=1" + l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)" + KPC() { + l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)" + l_pafile="$(grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc )" + l_fafile="$( + grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}' )" + if [ "$l_krp" = "$l_kpvalue" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration" + else + l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration" + fi + if [ -n "$l_pafile" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\"" + else + l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file" + fi + [ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\"" + } + for l_kpe in $l_parlist; do + l_kpname="$(awk -F= '{print $1}' <<<"$l_kpe")" + l_kpvalue="$(awk -F= '{print $2}' <<<"$l_kpe")" + KPC + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.7.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.7.sh new file mode 100644 index 0000000..75a6536 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.7.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_parlist="net.ipv4.conf.all.rp_filter=1 net.ipv4.conf.default.rp_filter=1" + l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)" + KPC() { + l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)" + l_pafile="$(grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc )" + l_fafile="$(grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}' )" + if [ "$l_krp" = "$l_kpvalue" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration" + else + l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration" + fi + if [ -n "$l_pafile" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\"" + else + l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file" + fi + [ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\"" + } + for l_kpe in $l_parlist; do + l_kpname="$(awk -F= '{print $1}' <<<"$l_kpe")" + l_kpvalue="$(awk -F= '{print $2}' <<<"$l_kpe")" + KPC + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.8.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.8.sh new file mode 100644 index 0000000..5d5bb06 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.8.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_parlist="net.ipv4.tcp_syncookies=1" + l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)" + KPC() { + l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)" + l_pafile="$(grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc)" + l_fafile="$( grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}' )" + if [ "$l_krp" = "$l_kpvalue" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration" + else + l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration" + fi + if [ -n "$l_pafile" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\"" + else + l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file" + fi + [ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\"" + } + for l_kpe in $l_parlist; do + l_kpname="$(awk -F= '{print $1}' <<<"$l_kpe")" + l_kpvalue="$(awk -F= '{print $2}' <<<"$l_kpe")" + KPC + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.9.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.9.sh new file mode 100644 index 0000000..c7890d6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.3.9.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_parlist="net.ipv6.conf.all.accept_ra=0 net.ipv6.conf.default.accept_ra=0" + l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)" + KPC() { + l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)" + l_pafile="$(grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc)" + l_fafile="$( + grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}' + )" + if [ "$l_krp" = "$l_kpvalue" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration" + else + l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration" + fi + if [ -n "$l_pafile" ]; then + l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\"" + else + l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file" + fi + [ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\"" + } + ipv6_chk() { + l_ipv6s="" + grubfile=$(find /boot -type f \( -name 'grubenv' -o -name 'grub.conf' -o -name 'grub.cfg' \) -exec grep -Pl -- '^\h*(kernelopts=|linux|kernel)' {} \; ) + if [ -s "$grubfile" ]; then + ! grep -P -- "^\h*(kernelopts=|linux|kernel)" "$grubfile" | grep -vq -- ipv6.disable=1 && l_ipv6s="disabled" + fi + if + grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\h*(#.*)?$" $l_searchloc && grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\h*(#.*)?$" $l_searchloc && sysctl net.ipv6.conf.all.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\h*(#.*)?$" && sysctl net.ipv6.conf.default.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\h*(#.*)?$" + then + l_ipv6s="disabled" + fi + if [ -n "$l_ipv6s" ]; then + l_output="$l_output\n - IPv6 is disabled on the system, \"$l_kpname\" is not applicable" + else + KPC + fi + } + for l_kpe in $l_parlist; do + l_kpname="$(awk -F= '{print $1}' <<<"$l_kpe")" + l_kpvalue="$(awk -F= '{print $2}' <<<"$l_kpe")" + if grep -q '^net.ipv6.' <<<"$l_kpe"; then + ipv6_chk + else + KPC + fi + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.5.1.6.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.5.1.6.sh new file mode 100644 index 0000000..5dbe49c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-3.5.1.6.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +ufw_out="$(ufw status verbose)" +ss -tuln | awk '($5!~/%lo:/ && $5!~/127.0.0.1:/ && $5!~/::1/) {split($5, a, ":"); print a[2]}' | sort | uniq | while read -r lpn; do + ! grep -Pq "^\h*$lpn\b" <<<"$ufw_out" && echo "- Port: \"$lpn\" is missing a firewall rule" +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.3.6-A.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.3.6-A.sh new file mode 100644 index 0000000..7edd572 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.3.6-A.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +for PARTITION in $(findmnt -n -l -k -it $( + awk '/nodev/ { print $2 }' /proc/filesystems | paste -sd, ) | grep -Pv "noexec|nosuid" | awk '{print $1}'); do + for PRIVILEGED in $(find "${PARTITION}" -xdev -perm /6000 -type f); do + grep -qr "${PRIVILEGED}" /etc/audit/rules.d && printf "OK:'${PRIVILEGED}' found in auditing rules.\n" || printf "Warning: '${PRIVILEGED}' not found in on disk configuration.\n" + done +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.3.6-B.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.3.6-B.sh new file mode 100644 index 0000000..39e4b16 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.3.6-B.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +{ + RUNNING=$(auditctl -l) + [ -n "${RUNNING}" ] && for PARTITION in $(findmnt -n -l -k -it $(awk '/nodev/ { print $2 }' /proc/filesystems | paste -sd,) | grep -Pv"noexec|nosuid" | awk '{print $1}'); do + for PRIVILEGED in $(find "${PARTITION}" -xdev -perm /6000 -type f); do + printf -- "${RUNNING}" | grep -q "${PRIVILEGED}" && printf "OK:'${PRIVILEGED}' found in auditing rules.\n" || printf "Warning:'${PRIVILEGED}' not found in running configuration.\n" + done + done || + printf "ERROR: Variable 'RUNNING' is unset.\n" +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.5.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.5.sh new file mode 100644 index 0000000..830c99e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.1.5.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +[ -f /etc/audit/auditd.conf ] && find "$(dirname $(awk -F "="'/^\s*log_file/ {print $2}' /etc/audit/auditd.conf | xargs))" -type f ! -user root -exec stat -Lc "%n %U" {} + \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.2.3.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.2.3.sh new file mode 100644 index 0000000..33f3d7e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-4.2.3.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +{ + echo -e "\n- Start check - logfiles have appropriate permissions and ownership" + output="" + find /var/log -type f | ( + while read -r fname; do + bname="$(basename "$fname")" + case "$bname" in lastlog | lastlog.* | wtmp | wtmp.* | btmp | btmp.*) + if ! stat -Lc "%a" "$fname" | grep -Pq -- '^\h*[0,2,4,6][0,2,4,6][0,4]\h*$'; then + output="$output\n- File: \"$fname\" mode: \"$(stat -Lc "%a" "$fname")\"\n" + fi + if ! stat -Lc "%U %G" "$fname" | grep -Pq -- '^\h*root\h+(utmp|root)\h*$'; then + output="$output\n- File: \"$fname\" ownership: \"$(stat -Lc "%U:%G" "$fname")\"\n" + fi + ;; + secure | auth.log) + if ! stat -Lc "%a" "$fname" | grep -Pq -- '^\h*[0,2,4,6][0,4]0\h*$'; then + output="$output\n- File: \"$fname\" mode: \"$(stat -Lc "%a" "$fname")\"\n" + fi + if ! stat -Lc "%U %G" "$fname" | grep -Pq -- '^\h*(syslog|root)\h+(adm|root)\h*$'; then + output="$output\n- File: \"$fname\" ownership: \"$(stat -Lc "%U:%G" "$fname")\"\n" + fi + ;; + SSSD | sssd) + if ! stat -Lc "%a" "$fname" | grep -Pq -- '^\h*[0,2,4,6][0,2,4,6]0\h*$'; then + output="$output\n- File: \"$fname\" mode: \"$(stat -Lc "%a" "$fname")\"\n" + fi + if ! stat -Lc "%U %G" "$fname" | grep -Piq -- '^\h*(SSSD|root)\h+(SSSD|root)\h*$'; then + output="$output\n- File: \"$fname\" ownership: \"$(stat -Lc "%U:%G" "$fname")\"\n" + fi + ;; + gdm | gdm3) + if ! stat -Lc "%a" "$fname" | grep -Pq -- '^\h*[0,2,4,6][0,2,4,6]0\h*$'; then + output="$output\n- File: \"$fname\" mode: \"$(stat -Lc "%a" "$fname")\"\n" + fi + if ! stat -Lc "%U %G" "$fname" | grep -Pq -- '^\h*(root)\h+(gdm3?|root)\h*$'; then + output="$output\n- File: \"$fname\" ownership: \"$(stat -Lc "%U:%G" "$fname")\"\n" + fi + ;; + *.journal) + if ! stat -Lc "%a" "$fname" | grep -Pq -- '^\h*[0,2,4,6][0,4]0\h*$'; then + output="$output\n- File: \"$fname\" mode: \"$(stat -Lc "%a" "$fname")\"\n" + fi + if ! stat -Lc "%U %G" "$fname" | grep -Pq -- '^\h*(root)\h+(systemd-journal|root)\h*$'; then + output="$output\n- File: \"$fname\" ownership: \"$(stat -Lc "%U:%G" "$fname")\"\n" + fi + ;; + *) + if ! stat -Lc "%a" "$fname" | grep -Pq -- '^\h*[0,2,4,6][0,4]0\h*$'; then + output="$output\n- File: \"$fname\" mode: \"$(stat -Lc "%a" "$fname")\"\n" + fi + if ! stat -Lc "%U %G" "$fname" | grep -Pq -- '^\h*(syslog|root)\h+(adm|root)\h*$'; then + output="$output\n- File: \"$fname\" ownership: \"$(stat -Lc "%U:%G" "$fname")\"\n" + fi + ;; + esac + done + # If all files passed, then we pass + if [ -z "$output" ]; then + echo -e "\n- PASS\n- All files in \"/var/log/\" have appropriate permissions and ownership\n" + else + # print the reason why we are failing + echo -e "\n- FAIL:\n$output" + fi + echo -e "- End check - logfiles have appropriate permissions and ownership\n" + ) +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.2.2.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.2.2.sh new file mode 100644 index 0000000..a10698e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.2.2.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +{ + l_output="" + l_skgn="ssh_keys" # Group designated to own openSSH keys + l_skgid="$(awk -F: '($1 == "'"$l_skgn"'"){print $3}' /etc/group)" + awk '{print}' <<<"$(find /etc/ssh -xdev -type f -name 'ssh_host_*_key' -exec stat -L -c "%n %#a %U %G %g" {} +)" | ( + while read -r l_file l_mode l_owner l_group l_gid; do + [ -n "$l_skgid" ] && l_cga="$l_skgn" || l_cga="root" + [ "$l_gid" = "$l_skgid" ] && l_pmask="0137" || l_pmask="0177" + l_maxperm="$(printf '%o' $((0777 & ~$l_pmask)))" + [ $(($l_mode & $l_pmask)) -gt 0 ] && l_output="$l_output\n - File: \"$l_file\" is mode \"$l_mode\" should be mode: \"$l_maxperm\" or more restrictive" + [ "$l_owner" != "root" ] && l_output="$l_output\n - File: \"$l_file\" is owned by: \"$l_owner\" should be owned by \"root\"" + if [ "$l_group" != "root" ] && [ "$l_gid" != "$l_skgid" ]; then + l_output="$l_output\n - File: \"$l_file\" is owned by group \"$l_group\" should belong to group \"$l_cga\"" + fi + done + if [ -z "$l_output" ]; then + echo -e "\n- Audit Result:\n *** PASS ***\n" + else + echo -e "\n- Audit Result:\n *** FAIL ***$l_output\n" + fi + ) +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.4.5.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.4.5.sh new file mode 100644 index 0000000..4f0f6e7 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.4.5.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +{ + declare -A HASH_MAP=(["y"]="yescrypt" ["1"]="md5" ["2"]="blowfish" + ["5"]="SHA256" ["6"]="SHA512" ["g"]="gost-yescrypt") + CONFIGURED_HASH=$(sed -n "s/^\s*ENCRYPT_METHOD\s*\(.*\)\s*$/\1/p" /etc/login.defs ) + for MY_USER in $(sed -n "s/^\(.*\):\\$.*/\1/p" /etc/shadow); do + CURRENT_HASH=$(sed -n "s/${MY_USER}:\\$\(.\).*/\1/p" /etc/shadow) + if [[ "${HASH_MAP["${CURRENT_HASH}"]^^}" != "${CONFIGURED_HASH^^}" ]]; then + echo "The password for '${MY_USER}' is using '${HASH_MAP["${CURRENT_HASH}"]}' instead of the configured '${CONFIGURED_HASH}'." + fi + done +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.1.5.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.1.5.sh new file mode 100644 index 0000000..45b638f --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.1.5.sh @@ -0,0 +1,9 @@ +#!/bin/bash +{ + awk -F: '/^[^:]+:[^!*]/{print $1}' /etc/shadow | while read -r usr; do + change=$(date -d "$(chage --list $usr | grep '^Last password change' | cut -d: -f2 | grep -v 'never$')" +%s) + if [[ "$change" -gt "$(date +%s)" ]]; then + echo "User: \"$usr\" last password change was \"$(chage --list $usr | grep '^Last password change' | cut -d: -f2)\"" + fi + done +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.2.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.2.sh new file mode 100644 index 0000000..2e36e2a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.2.sh @@ -0,0 +1,4 @@ +#!/bin/bash +awk -F: '$1!~/(root|sync|shutdown|halt|^\+)/ && $3<'"$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)"' && $7!~/((\/usr)?\/sbin\/nologin)/ && $7!~/(\/bin)?\/false/ {print}' /etc/passwd + +awk -F: '($1!~/(root|^\+)/ && $3<'"$( awk '/^\s*UID_MIN/{print $2}' /etc/login.defs )"') {print $1}' /etc/passwd | xargs -I '{}' passwd -S '{}' | awk '($2!~/LK?/) {print $1}' diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.4.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.4.sh new file mode 100644 index 0000000..baf7ed7 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.4.sh @@ -0,0 +1,7 @@ +#!/bin/bash +{ + passing="" + grep -Eiq '^\s*UMASK\s+(0[0-7][2-7]7|[0-7][2-7]7)\b' /etc/login.defs && grep -Eqi '^\s*USERGROUPS_ENAB\s*"?no"?\b' /etc/login.defs && grep -Eq '^\s*session\s+(optional|requisite|required)\s+pam_umask\.so\b' /etc/pam.d/common-session && passing=true + grep -REiq '^\s*UMASK\s+\s*(0[0-7][2-7]7|[0-7][2-7]7|u=(r?|w?|x?)(r?|w?|x?)(r?|w?|x?),g=(r?x?|x?r?),o=)\b' /etc/profile* /etc/bash.bashrc* && passing=true + [ "$passing" = true ] && echo "Default user umask is set" +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.5.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.5.sh new file mode 100644 index 0000000..82f1c81 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-5.5.5.sh @@ -0,0 +1,13 @@ +#!/bin/bash +output1="" output2="" +[ -f /etc/bash.bashrc ] && BRC="/etc/bash.bashrc" +for f in "$BRC" /etc/profile /etc/profile.d/*.sh; do + grep -Pq '^\s*([^#]+\s+)?TMOUT=(900|[1-8][0-9][0-9]|[1-9][0-9]|[1-9])\b' "$f" && grep -Pq '^\s*([^#]+;\s*)?readonly\s+TMOUT(\s+|\s*;|\s*$|=(900|[1-8][0-9][0-9]|[1-9][0-9]|[1-9]))\b' "$f" && grep -Pq '^\s*([^#]+;\s*)?export\s+TMOUT(\s+|\s*;|\s*$|=(900|[1-8][0-9][0-9]|[1-9][0-9]|[1-9]))\b' "$f" && output1="$f" +done +grep -Pq '^\s*([^#]+\s+)?TMOUT=(9[0-9][1-9]|9[1-9][0-9]|0+|[1-9]\d{3,})\b'/etc/profile /etc/profile.d/*.sh "$BRC" && output2=$(grep -Ps '^\s*([^#]+\s+)?TMOUT=(9[0-9][1-9]|9[1-9][0-9]|0+|[1-9]\d{3,})\b' /etc/profile /etc/profile.d/*.sh $BRC) +if [ -n "$output1" ] && [ -z "$output2" ]; then + echo -e "\nPASSED\n\nTMOUT is configured in: \"$output1\"\n" +else + [ -z "$output1" ] && echo -e "\nFAILED\n\nTMOUT is not configured\n" + [ -n "$output2" ] && echo -e "\nFAILED\n\nTMOUT is incorrectly configured in: \"$output2\"\n" +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.11.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.11.sh new file mode 100644 index 0000000..2ab903b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.11.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +{ + output="" + valid_shells="^($(sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | ( while read -r user home; do [ ! -d "$home" ] && output="$output\n - User \"$user\" home directory \"$home\" doesn't exist" + done + if [ -z "$output" ]; then + echo -e "\n-PASSED: - All local interactive users have a home directory\n" + else + echo -e "\n- FAILED:\n$output\n" + fi + ) +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.12.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.12.sh new file mode 100644 index 0000000..341f7f5 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.12.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +{ + output="" + valid_shells="^($(sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | (while read -r user home; do owner="$(stat -L -c "%U" "$home")" [ "$owner" != "$user" ] && output="$output\n - User \"$user\" home directory \"$home\" is owned by user \"$owner\"" + done + if [ -z "$output" ]; then + echo -e "\n-PASSED: - All local interactive users have a home directory\n" + else + echo -e "\n- FAILED:\n$output\n" + fi + ) +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.13.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.13.sh new file mode 100644 index 0000000..a1a97a8 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.13.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +{ + output="" + perm_mask='0027' + maxperm="$(printf '%o' $((0777 & ~$perm_mask)))" + valid_shells="^($(sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | ( + while read -r user home; do + if [ -d "$home" ]; then + mode=$(stat -L -c '%#a' "$home") + [ $(($mode & $perm_mask)) -gt 0 ] && output="$output\n- User $user home directory: \"$home\" is too permissive: \"$mode\" (should be: \"$maxperm\" or more restrictive)" + fi + done + if [ -n "$output" ]; then + echo -e "\n- Failed:$output" + else + echo -e "\n- Passed:\n- All user home directories are mode:\"$maxperm\" or more restrictive" + fi + ) +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.14.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.14.sh new file mode 100644 index 0000000..c68b429 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.14.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +{ + output="" output2="" + perm_mask='0177' + maxperm="$(printf '%o' $((0777 & ~$perm_mask)))" + valid_shells="^($(sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | ( + while read -r user home; do + if [ -f "$home/.netrc" ]; then + mode="$(stat -L -c '%#a' "$home/.netrc")" + if [ $(($mode & $perm_mask)) -gt 0 ]; then + output="$output\n - User \"$user\" file: \"$home/.netrc\" is too permissive: \"$mode\" (should be: \"$maxperm\" or more restrictive)" + else + output2="$output2\n - User \"$user\" file: \"$home/.netrc\" exists and has file mode: \"$mode\" (should be: \"$maxperm\" or more restrictive)" + fi + fi + done + if [ -z "$output" ]; then + if [ -z "$output2" ]; then + echo -e "\n-PASSED: - No local interactive users have \".netrc\" files in their home directory\n" + else + echo -e "\n- WARNING:\n$output2\n" + fi + else + echo -e "\n- FAILED:\n$output\n" + [ -n "$output2" ] && echo -e "\n- WARNING:\n$output2\n" + fi + ) +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.15.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.15.sh new file mode 100644 index 0000000..45d513a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.15.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +{ + output="" + fname=".forward" + valid_shells="^($(sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | ( + while read -r user home; do + [ -f "$home/$fname" ] && output="$output\n - User \"$user\" file: \"$home/$fname\" exists" + done + if [ -z "$output" ]; then + echo -e "\n-PASSED: - No local interactive users have \"$fname\" files in their home directory\n" + else + echo -e "\n- FAILED:\n$output\n" + fi + ) +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.16.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.16.sh new file mode 100644 index 0000000..445a1a9 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.16.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +{ + output="" + fname=".rhosts" + valid_shells="^($(sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | ( + while read -r user home; do + [ -f "$home/$fname" ] && output="$output\n - User \"$user\" file: \"$home/$fname\" exists" + done + if [ -z "$output" ]; then + echo -e "\n-PASSED: - No local interactive users have \"$fname\" files in their home directory\n" + else + echo -e "\n- FAILED:\n$output\n" + fi + ) +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.17.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.17.sh new file mode 100644 index 0000000..cc22adf --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.17.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +{ + output="" + perm_mask='0022' + maxperm="$(printf '%o' $((0777 & ~$perm_mask)))" + valid_shells="^($(sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | ( + while read -r user home; do + for dfile in $(find "$home" -type f -name '.*'); do + mode=$(stat -L -c '%#a' "$dfile") + [ $(($mode & $perm_mask)) -gt 0 ] && output="$output\n- User $user file: \"$dfile\" is too permissive: \"$mode\" (should be: \"$maxperm\" or more restrictive)" + done + done + if [ -n "$output" ]; then + echo -e "\n- Failed:$output" + else + echo -e "\n- Passed:\n- All user home dot files are mode: \"$maxperm\" or more restrictive" + fi + ) +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.3.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.3.sh new file mode 100644 index 0000000..afad21f --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.3.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +a_passwd_group_gid=("$(awk -F: '{print $4}' /etc/passwd | sort -u)") +a_group_gid=("$(awk -F: '{print $3}' /etc/group | sort -u)") +a_passwd_group_diff=("$(printf '%s\n' "${a_group_gid[@]}" "${a_passwd_group_gid[@]}" | sort | uniq -u)") +while IFS= read -r l_gid; do + awk -F: '($4 == '"$l_gid"') {print " - User: \"" $1 "\" has GID: \"" $4 "\" which does not exist in /etc/group" }' /etc/passwd + exit 1 +done < <(printf '%s\n' "${a_passwd_group_gid[@]}" "${a_passwd_group_diff[@]}" | sort | uniq -D | uniq) +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.5.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.5.sh new file mode 100644 index 0000000..7d12fdf --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.5.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +cut -f3 -d":" /etc/passwd | sort -n | uniq -c | while read x; do + [ -z "$x" ] && break + set - $x + if [ $1 -gt 1 ]; then + users=$(awk -F: '($3 == n) { print $1 }' n=$2 /etc/passwd | xargs) + echo "Duplicate UID ($2): $users" + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.6.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.6.sh new file mode 100644 index 0000000..09eb62c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.6.sh @@ -0,0 +1,4 @@ +#!/bin/bash +cut -d: -f3 /etc/group | sort | uniq -d | while read x; do + echo "Duplicate GID ($x) in /etc/group" +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.7.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.7.sh new file mode 100644 index 0000000..f5efc10 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.7.sh @@ -0,0 +1,4 @@ +#!/bin/bash +cut -d: -f1 /etc/passwd | sort | uniq -d | while read -r x; do + echo "Duplicate login name $x in /etc/passwd" +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.8.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.8.sh new file mode 100644 index 0000000..43eaaa4 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.8.sh @@ -0,0 +1,4 @@ +#!/bin/bash +cut -d: -f1 /etc/group | sort | uniq -d | while read -r x; do + echo "Duplicate group name $x in /etc/group" +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.9.sh b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.9.sh new file mode 100644 index 0000000..f5cc42e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Debian_11/CIS-Debian-6.2.9.sh @@ -0,0 +1,9 @@ +#!/bin/bash +awk -F: '($1!~/(root|halt|sync|shutdown)/ && $7!~/^(\/usr)?\/sbin\/nologin(\/)?$/ && $7!~/(\/usr)?\/bin\/false(\/)?$/) { print $1 " " $6 }' /etc/passwd | while read -r user dir; do + if [ -d "$dir" ]; then + file="$dir/.forward" + if [ ! -h "$file" ] && [ -f "$file" ]; then + echo "User: \"$user\" file: \"$file\" exists" + fi + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_1111.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_1111.sh new file mode 100644 index 0000000..caed61a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_1111.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_mname="squashfs" + test1=$(modprobe -n -v "$l_mname" 2>&1 | grep -Pi -- "\h*modprobe:\h+FATAL:\h+Module\h+$l_mname\h+not\h+found\h+in\h+directory") + if [ -z "$test1" ]; then + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<< "$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<< "$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<< "$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + if ! lsmod | grep "$l_mname" > /dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + if modprobe --showconfig | grep -Pq -- "^\h*blacklist\h+$l_mname\b"; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + else + l_output="$l_output\n - Module \"$l_mname\" doesn't exist on the system" + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_1112.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_1112.sh new file mode 100644 index 0000000..ee59d6a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_1112.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_mname="udf" + if [ -z "$(modprobe -n -v "$l_mname" 2>&1 | grep -Pi -- "\h*modprobe:\h+FATAL:\h+Module\h+$l_mname\h+not\h+found\h+in\h+directory")" ]; then + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<< "$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<< "$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<< "$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + if ! lsmod | grep "$l_mname" > /dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + if modprobe --showconfig | grep -Pq -- "^\h*blacklist\h+$l_mname\b"; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + else + l_output="$l_output\n - Module \"$l_mname\" doesn't exist on the system" + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_119.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_119.sh new file mode 100644 index 0000000..809efb6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_119.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + l_mname="usb-storage" + if [ -z '$(modprobe -n -v "$l_mname" 2>&1 | grep -Pi -- "\h*modprobe:\h+FATAL:\h+Module\h+$l_mname\h+not\h+found\h+in\h+directory")' ]; then + l_loadable='$(modprobe -n -v "$l_mname")' + [ "$(wc -l <<< "$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<< "$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<< "$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + if ! lsmod | grep "$l_mname" > /dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + if modprobe --showconfig | grep -Pq -- "^\h*blacklist\h+$(tr '-' '_' <<< "$l_mname")\b"; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + else + l_output="$l_output\n - Module \"$l_mname\" doesn't exist on the system" + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_182.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_182.sh new file mode 100644 index 0000000..3621d88 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_182.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + echo -e "$l_pkgoutput" + l_gdmfile="$(grep -Prils '^\h*banner-message-enable\b' /etc/dconf/db/*.d)" + if [ -n "$l_gdmfile" ]; then + l_gdmprofile="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<< "$l_gdmfile")" + if grep -Pisq '^\h*banner-message-enable=true\b' "$l_gdmfile"; then + l_output="$l_output\n - The \"banner-message-enable\" option is enabled in \"$l_gdmfile\"" + else + l_output2="$l_output2\n - The \"banner-message-enable\" option is not enabled" + fi + l_lsbt="$(grep -Pios '^\h*banner-message-text=.*$' "$l_gdmfile")" + if [ -n "$l_lsbt" ]; then + l_output="$l_output\n - The \"banner-message-text\" option is set in \"$l_gdmfile\"\n - banner-message-text is set to:\n - \"$l_lsbt\"" + else + l_output2="$l_output2\n - The \"banner-message-text\" option is not set" + fi + if grep -Pq "^\h*system-db:$l_gdmprofile" /etc/dconf/profile/"$l_gdmprofile"; then + l_output="$l_output\n - The \"$l_gdmprofile\" profile exists" + else + l_output2="$l_output2\n - The \"$l_gdmprofile\" profile doesn't exist" + fi + if [ -f "/etc/dconf/db/$l_gdmprofile" ]; then + l_output="$l_output\n - The \"$l_gdmprofile\" profile exists in the dconf database" + else + l_output2="$l_output2\n - The \"$l_gdmprofile\" profile doesn't exist in the dconf database" + fi + else + l_output2="$l_output2\n - The \"banner-message-enable\" option isn't configured" + fi + else + echo -e "\n\n - GNOME Desktop Manager isn't installed\n - Recommendation is Not Applicable\n- Audit result:\n *PASS*\n" + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_183.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_183.sh new file mode 100644 index 0000000..eb44b86 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_183.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + output="" output2="" + l_gdmfile="$(grep -Pril '^\h*disable-user-list\h*=\h*true\b' /etc/dconf/db)" + if [ -n "$l_gdmfile" ]; then + output="$output\n - The \"disable-user-list\" option is enabled in \"$l_gdmfile\"" + l_gdmprofile="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<< "$l_gdmfile")" + if grep -Pq "^\h*system-db:$l_gdmprofile" /etc/dconf/profile/"$l_gdmprofile"; then + output="$output\n - The \"$l_gdmprofile\" exists" + else + output2="$output2\n - The \"$l_gdmprofile\" doesn't exist" + fi + if [ -f "/etc/dconf/db/$l_gdmprofile" ]; then + output="$output\n - The \"$l_gdmprofile\" profile exists in the dconf database" + else + output2="$output2\n - The \"$l_gdmprofile\" profile doesn't exist in the dconf database" + fi + else + output2="$output2\n - The \"disable-user-list\" option is not enabled" + fi + if [ -z "$output2" ]; then + echo -e "$l_pkgoutput\n- Audit result:\n PASS:\n$output\n" + else + echo -e "$l_pkgoutput\n- Audit Result:\n FAIL:\n$output2\n" + [ -n "$output" ] && echo -e "$output\n" + fi + else + echo -e "\n\n - GNOME Desktop Manager isn't installed\n - Recommendation is Not Applicable\n- Audit result:\n PASS\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_184.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_184.sh new file mode 100644 index 0000000..874abc5 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_184.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" l_idmv="900" + l_ldmv="5" + l_kfile="$(grep -Psril '^\h*idle-delay\h*=\h*uint32\h+\d+\b' /etc/dconf/db/*/)" + if [ -n "$l_kfile" ]; then + l_profile="$(awk -F'/' '{split($(NF-1),a,".");print a[1]}' <<< "$l_kfile")" + l_pdbdir="/etc/dconf/db/$l_profile.d" + l_idv="$(awk -F 'uint32' '/idle-delay/{print $2}' "$l_kfile" | xargs)" + if [ -n "$l_idv" ]; then + [ "$l_idv" -gt "0" -a "$l_idv" -le "$l_idmv" ] && l_output="$l_output\n - The \"idle-delay\" option is set to \"$l_idv\" seconds in \"$l_kfile\"" [ "$l_idv" = "0" ] && l_output2="$l_output2\n - The \"idle-delay\" option is set to \"$l_idv\" (disabled) in \"$l_kfile\"" [ "$l_idv" -gt "$l_idmv" ] && l_output2="$l_output2\n - The \"idle-delay\" option is set to \"$l_idv\" seconds (greater than $l_idmv) in \"$l_kfile\"" + else + l_output2="$l_output2\n - The \"idle-delay\" option is not set in \"$l_kfile\"" + fi + l_ldv="$(awk -F 'uint32' '/lock-delay/{print $2}' "$l_kfile" | xargs)" + if [ -n "$l_ldv" ]; then + [ "$l_ldv" -ge "0" -a "$l_ldv" -le "$l_ldmv" ] && l_output="$l_output\n - The \"lock-delay\" option is set to \"$l_ldv\"seconds in \"$l_kfile\"" [ "$l_ldv" -gt "$l_ldmv" ] && l_output2="$l_output2\n - The \"lock-delay\" option is set to \"$l_ldv\" seconds (greater than $l_ldmv) in \"$l_kfile\"" + else + l_output2="$l_output2\n - The \"lock-delay\" option is not set in \"$l_kfile\"" + fi + if grep -Psq "^\h*system-db:$l_profile" /etc/dconf/profile/*; then + l_output="$l_output\n - The \"$l_profile\" profile exists" + else + l_output2="$l_output2\n - The \"$l_profile\" doesn't exist" + fi + if [ -f "/etc/dconf/db/$l_profile" ]; then + l_output="$l_output\n - The \"$l_profile\" profile exists in the dconf database" + else + l_output2="$l_output2\n - The \"$l_profile\" profile doesn't exist in the dconf database" + fi + else + l_output2="$l_output2\n - The \"idle-delay\" option doesn't exist, remaining tests skipped" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + [ -n "$l_pkgoutput" ] && echo -e "\n$l_pkgoutput" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_185.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_185.sh new file mode 100644 index 0000000..72282d3 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_185.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + l_kfd="/etc/dconf/db/$(grep -Psril '^\h*idle-delay\h*=\h*uint32\h+\d+\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" + l_kfd2="/etc/dconf/db/$(grep -Psril '^\h*lock-delay\h*=\h*uint32\h+\d+\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" + if [ -d "$l_kfd" ]; then + if grep -Prilq '\/org\/gnome\/desktop\/session\/idle-delay\b' "$l_kfd"; then + l_output="$l_output\n - \"idle-delay\" is locked in \"$(grep -Pril '\/org\/gnome\/desktop\/session\/idle-delay\b' "$l_kfd")\"" + else + l_output2="$l_output2\n - \"idle-delay\" is not locked" + fi + else + l_output2="$l_output2\n - \"idle-delay\" is not set so it can not be locked" + fi + if [ -d "$l_kfd2" ]; then + if grep -Prilq '\/org\/gnome\/desktop\/screensaver\/lock-delay\b' "$l_kfd2"; then + l_output="$l_output\n - \"lock-delay\" is locked in \"$(grep -Pril '\/org\/gnome\/desktop\/screensaver\/lock-delay\b' "$l_kfd2")\"" + else + l_output2="$l_output2\n - \"lock-delay\" is not locked" + fi + else + l_output2="$l_output2\n - \"lock-delay\" is not set so it can not be locked" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + [ -n "$l_pkgoutput" ] && echo -e "\n$l_pkgoutput" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_186.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_186.sh new file mode 100644 index 0000000..3ed9317 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_186.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" l_output="" l_output2="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + echo -e "$l_pkgoutput" + l_kfile="$(grep -Prils -- '^\h*automount\b' /etc/dconf/db/*.d)" + l_kfile2="$(grep -Prils -- '^\h*automount-open\b' /etc/dconf/db/*.d)" + if [ -f "$l_kfile" ]; then + l_gpname="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<< "$l_kfile")" + elif [ -f "$l_kfile2" ]; then + l_gpname="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<< "$l_kfile2")" + fi + if [ -n "$l_gpname" ]; then + l_gpdir="/etc/dconf/db/$l_gpname.d" + if grep -Pq -- "^\h*system-db:$l_gpname\b" /etc/dconf/profile/*; then + l_output="$l_output\n - dconf database profile file \"$(grep -Pl -- "^\h*system-db:$l_gpname\b" /etc/dconf/profile/*)\" exists" + else + l_output2="$l_output2\n - dconf database profile isn't set" + fi + if [ -f "/etc/dconf/db/$l_gpname" ]; then + l_output="$l_output\n - The dconf database \"$l_gpname\" exists" + else + l_output2="$l_output2\n - The dconf database \"$l_gpname\" doesn't exist" + fi + if [ -d "$l_gpdir" ]; then + l_output="$l_output\n - The dconf directory \"$l_gpdir\" exitst" + else + l_output2="$l_output2\n - The dconf directory \"$l_gpdir\" doesn't exist" + fi + if grep -Pqrs -- '^\h*automount\h*=\h*false\b' "$l_kfile"; then + l_output="$l_output\n - \"automount\" is set to false in: \"$l_kfile\"" + else + l_output2="$l_output2\n - \"automount\" is not set correctly" + fi + if grep -Pqs -- '^\h*automount-open\h*=\h*false\b' "$l_kfile2"; then + l_output="$l_output\n - \"automount-open\" is set to false in: \"$l_kfile2\"" + else + l_output2="$l_output2\n - \"automount-open\" is not set correctly" + fi + else + l_output2="$l_output2\n - neither \"automount\" or \"automount-open\" is set" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_187.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_187.sh new file mode 100644 index 0000000..f6e7c9e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_187.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + l_kfd="/etc/dconf/db/$(grep -Psril '^\h*automount\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" + l_kfd2="/etc/dconf/db/$(grep -Psril '^\h*automount-open\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" + if [ -d "$l_kfd" ]; then + if grep -Piq '^\h*\/org/gnome\/desktop\/media-handling\/automount\b' "$l_kfd"; then + l_output="$l_output\n - \"automount\" is locked in \"$(grep -Pil '^\h*\/org/gnome\/desktop\/media-handling\/automount\b' "$l_kfd")\"" + else + l_output2="$l_output2\n - \"automount\" is not locked" + fi + else + l_output2="$l_output2\n - \"automount\" is not set so it can not be locked" + fi + if [ -d "$l_kfd2" ]; then + if grep -Piq '^\h*\/org/gnome\/desktop\/media-handling\/automount-open\b' "$l_kfd2"; then + l_output="$l_output\n - \"lautomount-open\" is locked in \"$(grep -Pril '^\h*\/org/gnome\/desktop\/media-handling\/automount-open\b' "$l_kfd2")\"" + else + l_output2="$l_output2\n - \"automount-open\" is not locked" + fi + else + l_output2="$l_output2\n - \"automount-open\" is not set so it can not be locked" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + [ -n "$l_pkgoutput" ] && echo -e "\n$l_pkgoutput" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_188.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_188.sh new file mode 100644 index 0000000..f11261a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_188.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" l_output="" l_output2="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" echo -e "$l_pkgoutput" + done + if [ -n "$l_pkgoutput" ]; then + echo -e "$l_pkgoutput" + l_kfile="$(grep -Prils -- '^\h*autorun-never\b' /etc/dconf/db/*.d)" + if [ -f "$l_kfile" ]; then + l_gpname="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<< "$l_kfile")" + fi + if [ -n "$l_gpname" ]; then + l_gpdir="/etc/dconf/db/$l_gpname.d" + if grep -Pq -- "^\h*system-db:$l_gpname\b" /etc/dconf/profile/*; then + l_output="$l_output\n - dconf database profile file \"$(grep -Pl -- "^\h*system-db:$l_gpname\b" /etc/dconf/profile/*)\" exists" + else + l_output2="$l_output2\n - dconf database profile isn't set" + fi + if [ -f "/etc/dconf/db/$l_gpname" ]; then + l_output="$l_output\n - The dconf database \"$l_gpname\" exists" + else + l_output2="$l_output2\n - The dconf database \"$l_gpname\" doesn't exist" + fi + if [ -d "$l_gpdir" ]; then + l_output="$l_output\n - The dconf directory \"$l_gpdir\" exitst" + else + l_output2="$l_output2\n - The dconf directory \"$l_gpdir\" doesn't exist" + fi + if grep -Pqrs -- '^\h*autorun-never\h*=\h*true\b' "$l_kfile"; then + l_output="$l_output\n - \"autorun-never\" is set to true in: \"$l_kfile\"" + else + l_output2="$l_output2\n - \"autorun-never\" is not set correctly" + fi + else + l_output2="$l_output2\n - \"autorun-never\" is not set" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_189.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_189.sh new file mode 100644 index 0000000..4fbf6d3 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_189.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif + command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + l_kfd="/etc/dconf/db/$(grep -Psril '^\h*autorun-never\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" + if [ -d "$l_kfd" ]; then + if grep -Piq '^\h*\/org/gnome\/desktop\/media-handling\/autorun-never\b' "$l_kfd"; then + l_output="$l_output\n - \"autorun-never\" is locked in \"$(grep -Pil '^\h*\/org/gnome\/desktop\/media-handling\/autorun-never\b' "$l_kfd")\"" + else + l_output2="$l_output2\n - \"autorun-never\" is not locked" + fi + else + l_output2="$l_output2\n - \"autorun-never\" is not set so it can not be locked" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + [ -n "$l_pkgoutput" ] && echo -e "\n$l_pkgoutput" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_312.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_312.sh new file mode 100644 index 0000000..0d270d1 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_312.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" + module_chk() { + l_loadable="$(modprobe -n -v "$l_mname")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<< "$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + if ! lsmod | grep "$l_mname" > /dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + if modprobe --showconfig | grep -Pq -- "^\h*blacklist\h+$l_mname\b"; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + } + if [ -n "$(find /sys/class/net/*/ -type d -name wireless)" ]; then + l_dname=$(for driverdir in $(find /sys/class/net/*/ -type d -name wireless | xargs -0 dirname); do + basename "$(readlink -f "$driverdir"/device/driver/module)";done | sort -u) + for l_mname in $l_dname; do + module_chk + done + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS" + if [ -z "$l_output" ]; then + echo -e "\n - System has no wireless NICs installed" + else + echo -e "\n$l_output\n" + fi + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_313.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_313.sh new file mode 100644 index 0000000..4f2772c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_313.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" l_mname="tipc" + if [ -z "$(modprobe -n -v "$l_mname" 2>&1 | grep -Pi -- "\h*modprobe:\h+FATAL:\h+Module\h+$l_mname\h+not\h+found\h+in\h+directory")" ]; then + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<< "$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<< "$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<< "$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + if ! lsmod | grep "$l_mname" > /dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + if modprobe --showconfig | grep -Pq -- "^\h*blacklist\h+$l_mname\b"; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + else + l_output="$l_output\n - Module \"$l_mname\" doesn't exist on the system" + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_321.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_321.sh new file mode 100644 index 0000000..ed2523d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_321.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" l_kparameters="net.ipv4.ip_forward=0 net.ipv6.conf.all.forwarding=0" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)" + kernel_par_chk() + { + krp="" pafile="" fafile="" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" [ "$krp" = "$kpvalue" ] && l_output="$l_output\n - \"$kpname\" is set to \"$kpvalue\" in the running configuration" + [ -n "$pafile" ] && l_output="$l_output\n - \"$kpname\" is set to \"$kpvalue\" in \"$pafile\"" + [ -z "$fafile" ] && l_output="$l_output\n - \"$kpname\" is not set incorectly in a kernel parameter configuration file" [ "$krp" != "$kpvalue" ] && l_output2="$l_output2\n - \"$kpname\" is incorrectly set to \"$krp\" in the running configuration" + [ -n "$fafile" ] && l_output2="$l_output2\n - \"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && l_output2="$l_output2\n - \"$kpname = $kpvalue\" is not set in a kernel parameter configuration file" + } + for l_kpar in $l_kparameters; do + kpname="$(awk -F"=" '{print $1}' <<< "$l_kpar" | xargs)" kpvalue="$(awk -F"=" '{print $2}' <<< "$l_kpar" | xargs)" + if grep -Pq '^\h*net\.ipv6\.' <<< "$l_kpname"; then + if grep -Pqs '^\h*0\b' /sys/module/ipv6/parameters/disable; then + kernel_par_chk + else + l_output="$l_output\n - IPv6 is not enabled, check for: \"$l_kpar\" is not applicable" + fi + else + kernel_par_chk + fi + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_322_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_322_1.sh new file mode 100644 index 0000000..80d69a7 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_322_1.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv4.conf.all.send_redirects" kpvalue="0" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL " + [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_322_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_322_2.sh new file mode 100644 index 0000000..ab47dbf --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_322_2.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" kpname="net.ipv4.conf.default.send_redirects" kpvalue="0" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_11.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_11.sh new file mode 100644 index 0000000..cdafddf --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_11.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv4.conf.all.accept_source_route" kpvalue="0" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_12.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_12.sh new file mode 100644 index 0000000..2d8b016 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_12.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv4.conf.default.accept_source_route" kpvalue="0" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_21.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_21.sh new file mode 100644 index 0000000..c05f02c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_21.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv6.conf.all.accept_source_route" + kpvalue="0" searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_22.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_22.sh new file mode 100644 index 0000000..2a7347a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_331_22.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv4.conf.default.accept_source_route" kpvalue="0" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_11.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_11.sh new file mode 100644 index 0000000..f413be4 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_11.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv4.conf.all.accept_redirects" kpvalue="0" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_12.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_12.sh new file mode 100644 index 0000000..052c782 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_12.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv4.conf.default.accept_redirects" kpvalue="0" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_21.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_21.sh new file mode 100644 index 0000000..f99a9d7 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_21.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" kpname="net.ipv6.conf.all.accept_redirects" kpvalue="0" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_22.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_22.sh new file mode 100644 index 0000000..bb28ce6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_332_22.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv6.conf.default.accept_redirects" + kpvalue="0" searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_334_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_334_1.sh new file mode 100644 index 0000000..d715c4d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_334_1.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv4.conf.all.log_martians" kpvalue="1" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_334_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_334_2.sh new file mode 100644 index 0000000..6552c98 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_334_2.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv4.conf.default.accept_redirects" kpvalue="0" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_335.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_335.sh new file mode 100644 index 0000000..9a81d92 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_335.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv4.icmp_echo_ignore_broadcasts" + kpvalue="1" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_336.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_336.sh new file mode 100644 index 0000000..e634fb7 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_336.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv4.icmp_ignore_bogus_error_responses" kpvalue="1" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_337_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_337_1.sh new file mode 100644 index 0000000..5bdca20 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_337_1.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" kpname="net.ipv4.conf.all.rp_filter" kpvalue="1" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_337_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_337_2.sh new file mode 100644 index 0000000..dfd03aa --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_337_2.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv4.conf.default.rp_filter" + kpvalue="1" searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_338.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_338.sh new file mode 100644 index 0000000..ca201df --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_338.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" kpname="net.ipv4.tcp_syncookies" kpvalue="1" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_339_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_339_1.sh new file mode 100644 index 0000000..c3b4451 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_339_1.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" kpname="net.ipv6.conf.all.accept_ra" kpvalue="0" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_339_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_339_2.sh new file mode 100644 index 0000000..2e00244 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_339_2.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +{ + krp="" pafile="" fafile="" + kpname="net.ipv6.conf.default.accept_ra" kpvalue="0" + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + krp="$(sysctl "$kpname" | awk -F= '{print $2}' | xargs)" + pafile="$(grep -Psl -- "^\h*$kpname\h*=\h*$kpvalue\b\h*(#.*)?$" $searchloc)" + fafile="$(grep -s -- "^\s*$kpname" $searchloc | grep -Pv -- "\h*=\h*$kpvalue\b\h*" | awk -F: '{print $1}')" + if [ "$krp" = "$kpvalue" ] && [ -n "$pafile" ] && [ -z "$fafile" ]; then + echo -e "\nPASS:\n\"$kpname\" is set to \"$kpvalue\" in the running configuration and in \"$pafile\"" + else + echo -e "\nFAIL: " [ "$krp" != "$kpvalue" ] && echo -e "\"$kpname\" is set to \"$krp\" in the running configuration\n" + [ -n "$fafile" ] && echo -e "\n\"$kpname\" is set incorrectly in \"$fafile\"" + [ -z "$pafile" ] && echo -e "\n\"$kpname = $kpvalue\" is not set in a kernel parameter configuration file\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_3412.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_3412.sh new file mode 100644 index 0000000..b8f0893 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_3412.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" l_fwd_status="" l_nft_status="" l_fwutil_status="" + rpm -q firewalld > /dev/null 2>&1 && l_fwd_status="$(systemctl is-enabled firewalld.service):$(systemctl is-active firewalld.service)" + rpm -q nftables > /dev/null 2>&1 && l_nft_status="$(systemctl is-enabled nftables.service):$(systemctl is-active nftables.service)" + l_fwutil_status="$l_fwd_status:$l_nft_status" + case $l_fwutil_status in + enabled:active:masked:inactive|enabled:active:disabled:inactive) + l_output="\n - FirewallD utility is in use, enabled and active\n - NFTables utility is correctly disabled or masked and inactive" ;; + masked:inactive:enabled:active|disabled:inactive:enabled:active) + l_output="\n - NFTables utility is in use, enabled and active\n - FirewallD utility is correctly disabled or masked and inactive" ;; + enabled:active:enabled:active) + l_output2="\n - Both FirewallD and NFTables utilities are enabled and active" ;; + enabled:*:enabled:*) l_output2="\n - Both FirewallD and NFTables utilities are enabled" ;; + *:active:*:active) l_output2="\n - Both FirewallD and NFTables utilities are enabled" ;; + :enabled:active) l_output="\n - NFTables utility is in use, enabled, and active\n - FirewallD package is not installed" ;; + :) l_output2="\n - Neither FirewallD or NFTables is installed." ;; + *:*:) l_output2="\n - NFTables package is not installed on the system" ;; + *) l_output2="\n - Unable to determine firewall state" ;; + esac + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Results:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Results:\n FAIL\n$l_output2\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_3421.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_3421.sh new file mode 100644 index 0000000..852d59c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_3421.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" l_zone="" + if systemctl is-enabled firewalld.service | grep -q 'enabled'; then + l_zone="$(firewall-cmd --get-default-zone)" + if [ -n "$l_zone" ]; then + l_output=" - The default zone is set to: \"$l_zone\"" + else + l_output2=" - The default zone is not set" + fi + else + l_output=" - FirewallD is not in use on the system" + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Results:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Results:\n FAIL\n$l_output2\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41310_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41310_1.sh new file mode 100644 index 0000000..d6790ee --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41310_1.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && awk "/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -S/ &&/mount/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41310_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41310_2.sh new file mode 100644 index 0000000..609985d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41310_2.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && auditctl -l | awk "/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -S/ &&/mount/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41313_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41313_1.sh new file mode 100644 index 0000000..54445dc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41313_1.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && awk "/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -S/ &&(/unlink/||/rename/||/unlinkat/||/renameat/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41313_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41313_2.sh new file mode 100644 index 0000000..b33707d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41313_2.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && auditctl -l | awk "/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -S/ &&(/unlink/||/rename/||/unlinkat/||/renameat/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41314_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41314_1.sh new file mode 100644 index 0000000..eb8d1eb --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41314_1.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + awk '/^ *-w/ &&(/\/etc\/selinux/ ||/\/usr\/share\/selinux/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41314_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41314_2.sh new file mode 100644 index 0000000..bdd6815 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41314_2.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + auditctl -l | awk '/^ *-w/ &&(/\/etc\/selinux/ ||/\/usr\/share\/selinux/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41315_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41315_1.sh new file mode 100644 index 0000000..1385dfa --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41315_1.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/bin\/chcon/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41315_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41315_2.sh new file mode 100644 index 0000000..913e33e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41315_2.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && auditctl -l | awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/bin\/chcon/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41316_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41316_1.sh new file mode 100644 index 0000000..e8ac36b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41316_1.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/bin\/setfacl/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41316_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41316_2.sh new file mode 100644 index 0000000..7346f52 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41316_2.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && auditctl -l | awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/bin\/setfacl/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41317_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41317_1.sh new file mode 100644 index 0000000..c48d60f --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41317_1.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/bin\/chacl/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41317_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41317_2.sh new file mode 100644 index 0000000..985ec73 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41317_2.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && auditctl -l | awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/bin\/chacl/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41318_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41318_1.sh new file mode 100644 index 0000000..277666e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41318_1.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/sbin\/usermod/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41318_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41318_2.sh new file mode 100644 index 0000000..c919b9a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41318_2.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && auditctl -l | awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/sbin\/usermod/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41319_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41319_1.sh new file mode 100644 index 0000000..de470a3 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41319_1.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +{ + awk '/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F auid!=unset/||/ -F auid!=-1/||/ -F auid!=4294967295/) &&/ -S/ &&(/init_module/ ||/finit_module/ ||/delete_module/ ||/create_module/ ||/query_module/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/bin\/kmod/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41319_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41319_2.sh new file mode 100644 index 0000000..ea79b76 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_41319_2.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +{ + auditctl -l | awk '/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F auid!=unset/||/ -F auid!=-1/||/ -F auid!=4294967295/) &&/ -S/ &&(/init_module/ ||/finit_module/ ||/delete_module/ ||/create_module/ ||/query_module/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && auditctl -l | awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/bin\/kmod/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4133_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4133_1.sh new file mode 100644 index 0000000..3f96a98 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4133_1.sh @@ -0,0 +1,5 @@ + #!/usr/bin/env bash + { + SUDO_LOG_FILE_ESCAPED=$(grep -r logfile /etc/sudoers* | sed -e 's/.*logfile=//;s/,? .*//' -e 's/"//g' -e 's|/|\\/|g') + [ -n "${SUDO_LOG_FILE_ESCAPED}" ] && awk "/^ *-w/ \ &&/"${SUDO_LOG_FILE_ESCAPED}"/ &&/ +-p *wa/ \ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules || printf "ERROR: Variable 'SUDO_LOG_FILE_ESCAPED' is unset.\n" + } \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4133_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4133_2.sh new file mode 100644 index 0000000..9ce4e29 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4133_2.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + SUDO_LOG_FILE_ESCAPED=$(grep -r logfile /etc/sudoers* | sed -e 's/.*logfile=//;s/,? .*//' -e 's/"//g' -e 's|/|\\/|g') + [ -n "${SUDO_LOG_FILE_ESCAPED}" ] && auditctl -l | awk "/^ *-w/ &&/"${SUDO_LOG_FILE_ESCAPED}"/ \ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" \ || printf "ERROR: Variable 'SUDO_LOG_FILE_ESCAPED' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4136_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4136_1.sh new file mode 100644 index 0000000..2cbbce2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4136_1.sh @@ -0,0 +1,8 @@ + #!/usr/bin/env bash + { + for PARTITION in $(findmnt -n -l -k -it $(awk '/nodev/ { print $2 }' /proc/filesystems | paste -sd,) | grep -Pv "noexec|nosuid" | awk '{print $1}'); do + for PRIVILEGED in $(find "${PARTITION}" -xdev -perm /6000 -type f); do + grep -qr "${PRIVILEGED}" /etc/audit/rules.d && printf "OK: '${PRIVILEGED}' found in auditing rules.\n" || printf "Warning: '${PRIVILEGED}' not found in on disk configuration.\n" + done + done + } \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4136_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4136_2.sh new file mode 100644 index 0000000..84c0a97 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4136_2.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +{ + RUNNING=$(auditctl -l) + [ -n "${RUNNING}" ] && for PARTITION in $(findmnt -n -l -k -it $(awk '/nodev/ { print $2 }' /proc/filesystems | paste -sd,) | grep -Pv "noexec|nosuid" | awk '{print $1}'); do + for PRIVILEGED in $(find "${PARTITION}" -xdev -perm /6000 -type f); do + printf -- "${RUNNING}" | grep -q "${PRIVILEGED}" && printf "OK: '${PRIVILEGED}' found in auditing rules.\n" || printf "Warning: '${PRIVILEGED}' not found in running configuration.\n" + done + done || printf "ERROR: Variable 'RUNNING' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4137_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4137_1.sh new file mode 100644 index 0000000..a17f5a1 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4137_1.sh @@ -0,0 +1,5 @@ + #!/usr/bin/env bash + { + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && awk "/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&(/ -F *exit=-EACCES/||/ -F *exit=-EPERM/) &&/ -S/ &&/creat/ &&/open/ &&/truncate/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules || printf "ERROR: Variable 'UID_MIN' is unset.\n" + } \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4137_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4137_2.sh new file mode 100644 index 0000000..5fd8402 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4137_2.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && auditctl -l | awk "/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&(/ -F *exit=-EACCES/||/ -F *exit=-EPERM/) &&/ -S/ &&/creat/ &&/open/ &&/truncate/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4139_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4139_1.sh new file mode 100644 index 0000000..b4e350b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4139_1.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && awk "/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -S/ &&/ -F *auid>=${UID_MIN}/ &&(/chmod/||/fchmod/||/fchmodat/ ||/chown/||/fchown/||/fchownat/||/lchown/ ||/setxattr/||/lsetxattr/||/fsetxattr/ ||/removexattr/||/lremovexattr/||/fremovexattr/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4139_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4139_2.sh new file mode 100644 index 0000000..ae3b0be --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4139_2.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +{ + UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + [ -n "${UID_MIN}" ] && auditctl -l | awk "/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -S/ &&/ -F *auid>=${UID_MIN}/ &&(/chmod/||/fchmod/||/fchmodat/ ||/chown/||/fchown/||/fchownat/||/lchown/ ||/setxattr/||/lsetxattr/||/fsetxattr/ ||/removexattr/||/lremovexattr/||/fremovexattr/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" || printf "ERROR: Variable 'UID_MIN' is unset.\n" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4141.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4141.sh new file mode 100644 index 0000000..a09342a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4141.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + [ -f /etc/audit/auditd.conf ] && find "$(dirname $(awk -F "=" '/^\s*log_file/ {print $2}' /etc/audit/auditd.conf | xargs))" -type f \( ! -perm 600 -a ! -perm 0400 -a ! -perm 0200 -a ! -perm 0000 -a ! -perm 0640 -a ! -perm 0440 -a ! -perm 0040 \) -exec stat -Lc "%n %#a" {} + +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4142.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4142.sh new file mode 100644 index 0000000..c5c9fd7 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4142.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + [ -f /etc/audit/auditd.conf ] && find "$(dirname $(awk -F "=" '/^\s*log_file/ {print $2}' /etc/audit/auditd.conf | xargs))" -type f ! -user root -exec stat -Lc "%n %U" {} + +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4144.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4144.sh new file mode 100644 index 0000000..f409d0a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4144.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + stat -Lc "%n %a" "$(dirname $( awk -F"=" '/^\s*log_file\s*=\s*/ {print $2}' /etc/audit/auditd.conf))" | grep -Pv -- '^\h*\H+\h+([0,5,7][0,5]0)' +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4145.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4145.sh new file mode 100644 index 0000000..edabe95 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_4145.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + find /etc/audit/ -type f \( -name '*.conf' -o -name '*.rules' \) -exec stat -Lc "%n %a" {} + | grep -Pv -- '^\h*\H+\h*([0,2,4,6][0,4]0)\h*$' +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_522.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_522.sh new file mode 100644 index 0000000..2c32e60 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_522.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" l_skgn="ssh_keys" + l_skgid="$(awk -F: '($1 == "'"$l_skgn"'"){print $3}' /etc/group)" [ -n "$l_skgid" ] && l_cga="$l_skgn" || l_cga="root" awk '{print}' <<< "$(find -L /etc/ssh -xdev -type f -exec stat -Lc "%n %#a %U %G %g" {} +)" | (while read -r l_file l_mode l_owner l_group l_gid; do + if file "$l_file" | grep -Pq ':\h+OpenSSH\h+private\h+key\b'; then + [ "$l_gid" = "$l_skgid" ] && l_pmask="0137" || l_pmask="0177" l_maxperm="$( printf '%o' $(( 0777 & ~$l_pmask )) )" + if [ $(( $l_mode & $l_pmask )) -gt 0 ]; then + l_output2="$l_output2\n - File: \"$l_file\" is mode \"$l_mode\" should be mode: \"$l_maxperm\" or more restrictive" + else + l_output="$l_output\n - File: \"$l_file\" is mode \"$l_mode\" should be mode: \"$l_maxperm\" or more restrictive" + fi + if [ "$l_owner" != "root" ]; then + l_output2="$l_output2\n - File: \"$l_file\" is owned by: \"$l_owner\" should be owned by \"root\"" + else + l_output="$l_output\n - File: \"$l_file\" is owned by: \"$l_owner\" should be owned by \"root\"" + fi + if [ "$l_group" != "root" ] && [ "$l_gid" != "$l_skgid" ]; then + l_output2="$l_output2\n - File: \"$l_file\" is owned by group \"$l_group\" should belong to group \"$l_cga\"" + else + l_output="$l_output\n - File: \"$l_file\" is owned by group \"$l_group\" should belong to group \"$l_cga\"" + fi + fi + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n *PASS*\n$l_output" + else + echo -e "\n- Audit Result:\n *FAIL*\n$l_output2\n\n - Correctly set:\n$l_output" + fi + ) +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_523.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_523.sh new file mode 100644 index 0000000..f07ec86 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_523.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" l_pmask="0133" + awk '{print}' <<< "$(find -L /etc/ssh -xdev -type f -exec stat -Lc "%n %#a %U %G" {} +)" | (while read -r l_file l_mode l_owner l_group; do + if file "$l_file" | grep -Pq ':\h+OpenSSH\h+(\H+\h+)?public\h+key\b'; then + l_maxperm="$( printf '%o' $(( 0777 & ~$l_pmask )) )" + if [ $(( $l_mode & $l_pmask )) -gt 0 ]; then + l_output2="$l_output2\n - Public key file: \"$l_file\" is mode \"$l_mode\" should be mode: \"$l_maxperm\" or more restrictive" + else + l_output="$l_output\n - Public key file: \"$l_file\" is mode \"$l_mode\" should be mode: \"$l_maxperm\" or more restrictive" + fi + if [ "$l_owner" != "root" ]; then + l_output2="$l_output2\n - Public key file: \"$l_file\" is owned by: \"$l_owner\" should be owned by \"root\"" + else + l_output="$l_output\n - Public key file: \"$l_file\" is owned by: \"$l_owner\" should be owned by \"root\"" + fi + if [ "$l_group" != "root" ]; then + l_output2="$l_output2\n - Public key file: \"$l_file\" is owned by group \"$l_group\" should belong to group \"root\"\n" + else + l_output="$l_output\n - Public key file: \"$l_file\" is owned by group \"$l_group\" should belong to group \"root\"\n" + fi + fi + done + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n *PASS*\n$l_output" + else + echo -e "\n- Audit Result:\n *FAIL*\n$l_output2\n\n - Correctly set:\n$l_output" + fi + ) +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5611_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5611_1.sh new file mode 100644 index 0000000..78f3c11 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5611_1.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + grep PASS_MAX_DAYS /etc/login.defs | cut -d ' ' -f 2 +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5611_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5611_2.sh new file mode 100644 index 0000000..e0f4638 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5611_2.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + awk -F: '(/^[^:]+:[^!*]/ && ($5>365 || $5~/([0-1]|-1|\s*)/)){print $1 " " $5}' /etc/shadow +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5612_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5612_1.sh new file mode 100644 index 0000000..4928e93 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5612_1.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + grep PASS_MIN_DAYS /etc/login.defs | cut -d ' ' -f 2 +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5612_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5612_2.sh new file mode 100644 index 0000000..127acc2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5612_2.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + awk -F : '(/^[^:]+:[^!*]/ && $4 < 1){print $1 " " $4}' /etc/shadow +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5613_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5613_1.sh new file mode 100644 index 0000000..a99e7ce --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5613_1.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + grep PASS_WARN_AGE /etc/login.defs | cut -d ' ' -f 2 +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5613_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5613_2.sh new file mode 100644 index 0000000..6953fe9 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5613_2.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +{ + for var in $(grep -E ^[^:]+:[^\!*] /etc/shadow | cut -d: -f6) + do + if [ $var -le 7 ]; then + echo "FAIL" + fi + done +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5614_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5614_1.sh new file mode 100644 index 0000000..4724df0 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5614_1.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + useradd -D | grep INACTIVE | cut -d '=' -f 2 +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5614_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5614_2.sh new file mode 100644 index 0000000..191a5eb --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5614_2.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + awk -F: '/^[^#:]+:[^!\*:]*:[^:]*:[^:]*:[^:]*:[^:]*:(\s*|-1|3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):[^:]*:[^:]*\s*$/ {print $1":"$7}' /etc/shadow +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5615.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5615.sh new file mode 100644 index 0000000..5faf665 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_5615.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +{ + awk -F: '/^[^:]+:[^!*]/{print $1}' /etc/shadow | while read -r usr; do + change=$(date -d "$(chage --list $usr | grep '^Last password change' | cut -d: -f2 | grep -v 'never$')" +%s); + if [[ "$change" -gt "$(date +%s)" ]]; then + echo "User: \"$usr\" last password change was \"$(chage --list $usr | grep '^Last password change' | cut -d: -f2)\""; + fi; + done +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_562_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_562_1.sh new file mode 100644 index 0000000..ed7fd6f --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_562_1.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + awk -F: '($1!~/^(root|halt|sync|shutdown|nfsnobody)$/ && ($3<'"$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)"' || $3 == 65534) && $7!~/^(\/usr)?\/sbin\/nologin$/) { print $1 }' /etc/passwd +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_562_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_562_2.sh new file mode 100644 index 0000000..7e58cb5 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_562_2.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + awk -F: '/nologin/ {print $1}' /etc/passwd | xargs -I '{}' passwd -S '{}' | awk '($2!="L" && $2!="LK") {print $1}' +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_565_1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_565_1.sh new file mode 100644 index 0000000..d74ebd9 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_565_1.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +{ + passing="" + grep -Eiq '^\s*UMASK\s+(0[0-7][2-7]7|[0-7][2-7]7)\b' /etc/login.defs && grep -Eqi '^\s*USERGROUPS_ENAB\s*"?no"?\b' /etc/login.defs && grep -Eq '^\s*session\s+(optional|requisite|required)\s+pam_umask\.so\b' /etc/pam.d/common-session && passing=true grep -REiq '^\s*UMASK\s+\s*(0[0-7][2-7]7|[0-7][2-7]7|u=(r?|w?|x?)(r?|w?|x?)(r?|w?|x?),g=(r?x?|x?r?),o=)\b' /etc/profile* /etc/bashrc* && passing=true + [ "$passing" = true ] && echo "Default user umask is set" +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_565_2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_565_2.sh new file mode 100644 index 0000000..72f6a44 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_565_2.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + grep -RPi '(^|^[^#]*)\s*umask\s+([0-7][0-7][01][0-7]\b|[0-7][0-7][0-7][0-6]\b|[0-7][01][0-7]\b|[0-7][0-7][0-6]\b|(u=[rwx]{0,3},)?(g=[rwx]{0,3},)?o=[rwx]+\b|(u=[rwx]{1,3},)?g=[^rx]{1,3}(,o=[rwx]{0,3})?\b)' /etc/login.defs /etc/profile* /etc/bashrc* +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_621.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_621.sh new file mode 100644 index 0000000..8a41221 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_621.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + awk -F: '($2 != "x" ) { print $1 " is not set to shadowed passwords "}' /etc/passwd +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6210.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6210.sh new file mode 100644 index 0000000..f2d2f79 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6210.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +{ + output="" + valid_shells="^($( sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | (while read -r user home; do + [ ! -d "$home" ] && output="$output\n - User \"$user\" home directory \"$home\" doesn't exist" + done + if [ -z "$output" ]; then + echo -e "\n-PASSED: - All local interactive users have a home directory\n" + else + echo -e "\n- FAILED:\n$output\n" + fi + ) +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6211.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6211.sh new file mode 100644 index 0000000..ef63bd4 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6211.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +{ + output="" + valid_shells="^($( sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | (while read -r user home; do + owner="$(stat -L -c "%U" "$home")" [ "$owner" != "$user" ] && output="$output\n - User \"$user\" home directory \"$home\" is owned by user \"$owner\"" + done + if [ -z "$output" ]; then + echo -e "\n-PASSED: - All local interactive users have a home directory\n" + else + echo -e "\n- FAILED:\n$output\n" + fi + ) +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6212.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6212.sh new file mode 100644 index 0000000..cc2aa52 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6212.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +{ + output="" + perm_mask='0027' + maxperm="$( printf '%o' $(( 0777 & ~$perm_mask)) )" valid_shells="^($( sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | (while read -r user home; do + mode=$( stat -L -c '%#a' "$home" ) + [ $(( $mode & $perm_mask )) -gt 0 ] && output="$output\n- User $user home directory: \"$home\" is too permissive: \"$mode\" (should be: \"$maxperm\" or more restrictive)" + done + if [ -n "$output" ]; then + echo -e "\n- Failed:$output" + else + echo -e "\n- Passed:\n- All user home directories are mode: \"$maxperm\" or more restrictive" + fi + ) +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6213.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6213.sh new file mode 100644 index 0000000..972848b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6213.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +{ + output="" output2="" perm_mask='0177' + maxperm="$( printf '%o' $(( 0777 & ~$perm_mask)) )" + valid_shells="^($( sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | (while read -r user home; do + if [ -f "$home/.netrc" ]; then mode="$( stat -L -c '%#a' "$home/.netrc" )" + if [ $(( $mode & $perm_mask )) -gt 0 ]; then + output="$output\n - User \"$user\" file: \"$home/.netrc\" is too permissive: \"$mode\" (should be: \"$maxperm\" or more restrictive)" + else + output2="$output2\n - User \"$user\" file: \"$home/.netrc\" exists and has file mode: \"$mode\" (should be: \"$maxperm\" or more restrictive)" + fi + fi + done + if [ -z "$output" ]; then + if [ -z "$output2" ]; then + echo -e "\n-PASSED: - No local interactive users have \".netrc\" files in their home directory\n" + else + echo -e "\n- WARNING:\n$output2\n" + fi + else + echo -e "\n- FAILED:\n$output\n" [ -n "$output2" ] && echo -e "\n- WARNING:\n$output2\n" + fi + ) +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6214.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6214.sh new file mode 100644 index 0000000..8bd3a99 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6214.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +{ + output="" + fname=".forward" + valid_shells="^($( sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | (while read -r user home; do + [ -f "$home/$fname" ] && output="$output\n - User \"$user\" file: \"$home/$fname\" exists" + done + if [ -z "$output" ]; then + echo -e "\n-PASSED: - No local interactive users have \"$fname\" files in their home directory\n" + else + echo -e "\n- FAILED:\n$output\n" + fi + ) +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6215.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6215.sh new file mode 100644 index 0000000..1bf982e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6215.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +{ + output="" + fname=".rhosts" + valid_shells="^($( sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | (while read -r user home; do + [ -f "$home/$fname" ] && output="$output\n - User \"$user\" file: \"$home/$fname\" exists" + done + if [ -z "$output" ]; then + echo -e "\n-PASSED: - No local interactive users have \"$fname\" files in their home directory\n" + else + echo -e "\n- FAILED:\n$output\n" + fi + ) +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6216.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6216.sh new file mode 100644 index 0000000..238eafe --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_6216.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +{ + output="" + perm_mask='0022' + maxperm="$( printf '%o' $(( 0777 & ~$perm_mask)) )" + valid_shells="^($( sed -rn '/^\//{s,/,\\\\/,g;p}' /etc/shells | paste -s -d '|' - ))$" + awk -v pat="$valid_shells" -F: '$(NF) ~ pat { print $1 " " $(NF-1) }' /etc/passwd | (while read -r user home; do + for dfile in $(find "$home" -type f -name '.*'); do + mode=$( stat -L -c '%#a' "$dfile" ) + [ $(( $mode & $perm_mask )) -gt 0 ] && output="$output\n- User $user file: \"$dfile\" is too permissive: \"$mode\" (should be: \"$maxperm\" or more restrictive)" + done + done + if [ -n "$output" ]; then + echo -e "\n- Failed:$output" + else + echo -e "\n- Passed:\n- All user home dot files are mode: \"$maxperm\" or more restrictive" + fi + ) +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_622.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_622.sh new file mode 100644 index 0000000..2e5e69e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_622.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + awk -F: '($2 == "" ) { print $1 " does not have a password "}' /etc/shadow +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_628.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_628.sh new file mode 100644 index 0000000..3ef3663 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_628.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +{ + RPCV="$(sudo -Hiu root env | grep '^PATH' | cut -d= -f2)" + echo "$RPCV" | grep -q "::" && echo "root's path contains a empty directory (::)" + echo "$RPCV" | grep -q ":$" && echo "root's path contains a trailing (:)" + for x in $(echo "$RPCV" | tr ":" " "); do + if [ -d "$x" ]; then + ls -ldH "$x" | awk '$9 == "." {print "PATH contains current working directory (.)"} + $3 != "root" {print $9, "is not owned by root"} + substr($1,6,1) != "-" {print $9, "is group writable"} + substr($1,9,1) != "-" {print $9, "is world writable"}' + else + echo "$x is not a directory" + fi + done +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_629.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_629.sh new file mode 100644 index 0000000..14b6a5b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9/CIS100_RHEL9_629.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + awk -F: '($3 == 0) { print $1 }' /etc/passwd +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.2.1.2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.2.1.2.sh new file mode 100644 index 0000000..9eeadde --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.2.1.2.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# Configuration file to check +FILE="/etc/dnf/dnf.conf" +# Pattern to search for +PATTERN="gpgcheck" + +# Check if the configuration file exists +if [ ! -f "$FILE" ]; then + echo "File $FILE not found." + exit 1 +fi + +# Search for the pattern, whether it's commented or not +grep -E "^[[:space:]]*#?[[:space:]]*$PATTERN\s*=" "$FILE" >/dev/null +FOUND=$? + +# If the pattern is found +if [ $FOUND -eq 0 ]; then + # Check if the pattern is commented + grep -E "^[[:space:]]*#[[:space:]]*$PATTERN\s*=" "$FILE" >/dev/null + COMMENTED=$? + + if [ $COMMENTED -eq 0 ]; then + echo "Pattern $PATTERN is commented." + exit 1 + fi + + # Extract the value of gpgcheck using grep and sed + VALUE=$(grep -E "^[[:space:]]*$PATTERN\s*=\s*(true|yes|[0-9]+)" "$FILE" | sed -E 's/.*=\s*(true|yes|[0-9]+).*/\1/') + + # If the value was found and it's valid (true, yes, or 1) + if [[ "$VALUE" == "true" || "$VALUE" == "yes" || "$VALUE" == "1" ]]; then + echo "The value of $PATTERN ($VALUE) is valid." + exit 0 + else + echo "The value of $PATTERN ($VALUE) is not valid." + exit 1 + fi +else + echo "Pattern $PATTERN not found." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.3.1.2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.3.1.2.sh new file mode 100644 index 0000000..4f6f2e0 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.3.1.2.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +if grubby --info=ALL | grep -Pq '(selinux|enforcing)=0\b'; then + exit 1 +else + exit 0 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.3.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.3.1.3.sh new file mode 100644 index 0000000..c8153f8 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.3.1.3.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +if grep -Eq '^\s*SELINUXTYPE=(targeted|mls)\b' /etc/selinux/config; then + echo "SELinux-Type is configured correctly" + exit 0 +else + echo "ERROR: SELinux-Type not configured" + exit 1 +fi + +if sestatus | grep -q "Loaded policy name: targeted"; then + echo "Policy is'targeted'" + exit 0 +elif sestatus | grep -q "Loaded policy name: mls"; then + echo "ERROR: Policy is 'mls'" + exit 1 +else + echo "ERROR: policy should be 'targeted'" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.3.1.5.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.3.1.5.sh new file mode 100644 index 0000000..d01b813 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.3.1.5.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +if grep -i SELINUX=enforcing /etc/selinux/config; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.5.3.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.5.3.sh new file mode 100644 index 0000000..20b1d2c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.5.3.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +for file in /etc/systemd/coredump.conf /etc/systemd/coredump.conf.d/*.conf; do + [ -e "$file" ] || continue + + if grep -Eq '^\s*ProcessSizeMax=0' "$file"; then + exit 0 + fi + +done + +exit 1 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.5.4.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.5.4.sh new file mode 100644 index 0000000..633b85c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.5.4.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +for file in /etc/systemd/coredump.conf /etc/systemd/coredump.conf.d/*.conf; do + [ -e "$file" ] || continue + + if grep -Eq '^\s*Storage=none' "$file"; then + exit 0 + fi + +done + +exit 1 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.6.1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.6.1.sh new file mode 100644 index 0000000..a778f03 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.6.1.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +grep -q "^1$" /proc/sys/crypto/fips_enabled && exit 0 +grep -q "^LEGACY$" /etc/crypto-policies/config && exit 1 || exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.6.2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.6.2.sh new file mode 100644 index 0000000..b5f9bff --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.6.2.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +if [[ -f /etc/sysconfig/sshd ]]; then + if grep -Pi '^\s*CRYPTO_POLICY\s*=' /etc/sysconfig/sshd; then + echo "CRYPTO_POLICY ist set" + exit 1 + else + echo "CRYPTO_POLICY is not set" + fi +else + echo "file /etc/sysconfig/sshd does not exist" +fi +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.7.1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.7.1.sh new file mode 100644 index 0000000..373e1cc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.7.1.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# Extract the OS ID from /etc/os-release +OS_ID=$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g') + +# Run the grep command with the OS ID incorporated +grep -Eis "(\\v|\\r|\\m|\\s|$OS_ID)" /etc/motd + +# Check the exit code of the grep command +if [ $? -ne 0 ]; then + # Grep did not find any matches, return 0 + exit 0 +else + # Grep found matches, return 1 + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.7.4.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.7.4.sh new file mode 100644 index 0000000..a2766e2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.7.4.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +TEST_FILE="/etc/motd" +if [ -e "$TEST_FILE" ]; then + DESIRED_PERM="644" + ACTUAL_PERM=$(stat -c "%a" "$TEST_FILE") + if [[ "$ACTUAL_PERM" == "$DESIRED_PERM" ]]; then + exit 0 + else + exit 1 + fi +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.10.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.10.sh new file mode 100644 index 0000000..d21b15d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.10.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +config_file="/etc/gdm/custom.conf" + +if [[ ! -f "$config_file" || ! -r "$config_file" ]]; then + exit 0 +fi + +value="Enable" + +if grep -Eq "^\s*$value\s*=\s*true\s*$" "$config_file"; then + echo -e " \"$value\" in $config_file is true" + exit 1 +else + echo -e "\"$value\" not found or not set " +fi +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.2.sh new file mode 100644 index 0000000..3621d88 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.2.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + echo -e "$l_pkgoutput" + l_gdmfile="$(grep -Prils '^\h*banner-message-enable\b' /etc/dconf/db/*.d)" + if [ -n "$l_gdmfile" ]; then + l_gdmprofile="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<< "$l_gdmfile")" + if grep -Pisq '^\h*banner-message-enable=true\b' "$l_gdmfile"; then + l_output="$l_output\n - The \"banner-message-enable\" option is enabled in \"$l_gdmfile\"" + else + l_output2="$l_output2\n - The \"banner-message-enable\" option is not enabled" + fi + l_lsbt="$(grep -Pios '^\h*banner-message-text=.*$' "$l_gdmfile")" + if [ -n "$l_lsbt" ]; then + l_output="$l_output\n - The \"banner-message-text\" option is set in \"$l_gdmfile\"\n - banner-message-text is set to:\n - \"$l_lsbt\"" + else + l_output2="$l_output2\n - The \"banner-message-text\" option is not set" + fi + if grep -Pq "^\h*system-db:$l_gdmprofile" /etc/dconf/profile/"$l_gdmprofile"; then + l_output="$l_output\n - The \"$l_gdmprofile\" profile exists" + else + l_output2="$l_output2\n - The \"$l_gdmprofile\" profile doesn't exist" + fi + if [ -f "/etc/dconf/db/$l_gdmprofile" ]; then + l_output="$l_output\n - The \"$l_gdmprofile\" profile exists in the dconf database" + else + l_output2="$l_output2\n - The \"$l_gdmprofile\" profile doesn't exist in the dconf database" + fi + else + l_output2="$l_output2\n - The \"banner-message-enable\" option isn't configured" + fi + else + echo -e "\n\n - GNOME Desktop Manager isn't installed\n - Recommendation is Not Applicable\n- Audit result:\n *PASS*\n" + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.3.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.3.sh new file mode 100644 index 0000000..eb44b86 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.3.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + output="" output2="" + l_gdmfile="$(grep -Pril '^\h*disable-user-list\h*=\h*true\b' /etc/dconf/db)" + if [ -n "$l_gdmfile" ]; then + output="$output\n - The \"disable-user-list\" option is enabled in \"$l_gdmfile\"" + l_gdmprofile="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<< "$l_gdmfile")" + if grep -Pq "^\h*system-db:$l_gdmprofile" /etc/dconf/profile/"$l_gdmprofile"; then + output="$output\n - The \"$l_gdmprofile\" exists" + else + output2="$output2\n - The \"$l_gdmprofile\" doesn't exist" + fi + if [ -f "/etc/dconf/db/$l_gdmprofile" ]; then + output="$output\n - The \"$l_gdmprofile\" profile exists in the dconf database" + else + output2="$output2\n - The \"$l_gdmprofile\" profile doesn't exist in the dconf database" + fi + else + output2="$output2\n - The \"disable-user-list\" option is not enabled" + fi + if [ -z "$output2" ]; then + echo -e "$l_pkgoutput\n- Audit result:\n PASS:\n$output\n" + else + echo -e "$l_pkgoutput\n- Audit Result:\n FAIL:\n$output2\n" + [ -n "$output" ] && echo -e "$output\n" + fi + else + echo -e "\n\n - GNOME Desktop Manager isn't installed\n - Recommendation is Not Applicable\n- Audit result:\n PASS\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.4.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.4.sh new file mode 100644 index 0000000..874abc5 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.4.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" l_idmv="900" + l_ldmv="5" + l_kfile="$(grep -Psril '^\h*idle-delay\h*=\h*uint32\h+\d+\b' /etc/dconf/db/*/)" + if [ -n "$l_kfile" ]; then + l_profile="$(awk -F'/' '{split($(NF-1),a,".");print a[1]}' <<< "$l_kfile")" + l_pdbdir="/etc/dconf/db/$l_profile.d" + l_idv="$(awk -F 'uint32' '/idle-delay/{print $2}' "$l_kfile" | xargs)" + if [ -n "$l_idv" ]; then + [ "$l_idv" -gt "0" -a "$l_idv" -le "$l_idmv" ] && l_output="$l_output\n - The \"idle-delay\" option is set to \"$l_idv\" seconds in \"$l_kfile\"" [ "$l_idv" = "0" ] && l_output2="$l_output2\n - The \"idle-delay\" option is set to \"$l_idv\" (disabled) in \"$l_kfile\"" [ "$l_idv" -gt "$l_idmv" ] && l_output2="$l_output2\n - The \"idle-delay\" option is set to \"$l_idv\" seconds (greater than $l_idmv) in \"$l_kfile\"" + else + l_output2="$l_output2\n - The \"idle-delay\" option is not set in \"$l_kfile\"" + fi + l_ldv="$(awk -F 'uint32' '/lock-delay/{print $2}' "$l_kfile" | xargs)" + if [ -n "$l_ldv" ]; then + [ "$l_ldv" -ge "0" -a "$l_ldv" -le "$l_ldmv" ] && l_output="$l_output\n - The \"lock-delay\" option is set to \"$l_ldv\"seconds in \"$l_kfile\"" [ "$l_ldv" -gt "$l_ldmv" ] && l_output2="$l_output2\n - The \"lock-delay\" option is set to \"$l_ldv\" seconds (greater than $l_ldmv) in \"$l_kfile\"" + else + l_output2="$l_output2\n - The \"lock-delay\" option is not set in \"$l_kfile\"" + fi + if grep -Psq "^\h*system-db:$l_profile" /etc/dconf/profile/*; then + l_output="$l_output\n - The \"$l_profile\" profile exists" + else + l_output2="$l_output2\n - The \"$l_profile\" doesn't exist" + fi + if [ -f "/etc/dconf/db/$l_profile" ]; then + l_output="$l_output\n - The \"$l_profile\" profile exists in the dconf database" + else + l_output2="$l_output2\n - The \"$l_profile\" profile doesn't exist in the dconf database" + fi + else + l_output2="$l_output2\n - The \"idle-delay\" option doesn't exist, remaining tests skipped" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + [ -n "$l_pkgoutput" ] && echo -e "\n$l_pkgoutput" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.5.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.5.sh new file mode 100644 index 0000000..72282d3 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.5.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + l_kfd="/etc/dconf/db/$(grep -Psril '^\h*idle-delay\h*=\h*uint32\h+\d+\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" + l_kfd2="/etc/dconf/db/$(grep -Psril '^\h*lock-delay\h*=\h*uint32\h+\d+\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" + if [ -d "$l_kfd" ]; then + if grep -Prilq '\/org\/gnome\/desktop\/session\/idle-delay\b' "$l_kfd"; then + l_output="$l_output\n - \"idle-delay\" is locked in \"$(grep -Pril '\/org\/gnome\/desktop\/session\/idle-delay\b' "$l_kfd")\"" + else + l_output2="$l_output2\n - \"idle-delay\" is not locked" + fi + else + l_output2="$l_output2\n - \"idle-delay\" is not set so it can not be locked" + fi + if [ -d "$l_kfd2" ]; then + if grep -Prilq '\/org\/gnome\/desktop\/screensaver\/lock-delay\b' "$l_kfd2"; then + l_output="$l_output\n - \"lock-delay\" is locked in \"$(grep -Pril '\/org\/gnome\/desktop\/screensaver\/lock-delay\b' "$l_kfd2")\"" + else + l_output2="$l_output2\n - \"lock-delay\" is not locked" + fi + else + l_output2="$l_output2\n - \"lock-delay\" is not set so it can not be locked" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + [ -n "$l_pkgoutput" ] && echo -e "\n$l_pkgoutput" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.6.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.6.sh new file mode 100644 index 0000000..3ed9317 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.6.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" l_output="" l_output2="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + echo -e "$l_pkgoutput" + l_kfile="$(grep -Prils -- '^\h*automount\b' /etc/dconf/db/*.d)" + l_kfile2="$(grep -Prils -- '^\h*automount-open\b' /etc/dconf/db/*.d)" + if [ -f "$l_kfile" ]; then + l_gpname="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<< "$l_kfile")" + elif [ -f "$l_kfile2" ]; then + l_gpname="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<< "$l_kfile2")" + fi + if [ -n "$l_gpname" ]; then + l_gpdir="/etc/dconf/db/$l_gpname.d" + if grep -Pq -- "^\h*system-db:$l_gpname\b" /etc/dconf/profile/*; then + l_output="$l_output\n - dconf database profile file \"$(grep -Pl -- "^\h*system-db:$l_gpname\b" /etc/dconf/profile/*)\" exists" + else + l_output2="$l_output2\n - dconf database profile isn't set" + fi + if [ -f "/etc/dconf/db/$l_gpname" ]; then + l_output="$l_output\n - The dconf database \"$l_gpname\" exists" + else + l_output2="$l_output2\n - The dconf database \"$l_gpname\" doesn't exist" + fi + if [ -d "$l_gpdir" ]; then + l_output="$l_output\n - The dconf directory \"$l_gpdir\" exitst" + else + l_output2="$l_output2\n - The dconf directory \"$l_gpdir\" doesn't exist" + fi + if grep -Pqrs -- '^\h*automount\h*=\h*false\b' "$l_kfile"; then + l_output="$l_output\n - \"automount\" is set to false in: \"$l_kfile\"" + else + l_output2="$l_output2\n - \"automount\" is not set correctly" + fi + if grep -Pqs -- '^\h*automount-open\h*=\h*false\b' "$l_kfile2"; then + l_output="$l_output\n - \"automount-open\" is set to false in: \"$l_kfile2\"" + else + l_output2="$l_output2\n - \"automount-open\" is not set correctly" + fi + else + l_output2="$l_output2\n - neither \"automount\" or \"automount-open\" is set" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.7.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.7.sh new file mode 100644 index 0000000..f6e7c9e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.7.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + l_kfd="/etc/dconf/db/$(grep -Psril '^\h*automount\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" + l_kfd2="/etc/dconf/db/$(grep -Psril '^\h*automount-open\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" + if [ -d "$l_kfd" ]; then + if grep -Piq '^\h*\/org/gnome\/desktop\/media-handling\/automount\b' "$l_kfd"; then + l_output="$l_output\n - \"automount\" is locked in \"$(grep -Pil '^\h*\/org/gnome\/desktop\/media-handling\/automount\b' "$l_kfd")\"" + else + l_output2="$l_output2\n - \"automount\" is not locked" + fi + else + l_output2="$l_output2\n - \"automount\" is not set so it can not be locked" + fi + if [ -d "$l_kfd2" ]; then + if grep -Piq '^\h*\/org/gnome\/desktop\/media-handling\/automount-open\b' "$l_kfd2"; then + l_output="$l_output\n - \"lautomount-open\" is locked in \"$(grep -Pril '^\h*\/org/gnome\/desktop\/media-handling\/automount-open\b' "$l_kfd2")\"" + else + l_output2="$l_output2\n - \"automount-open\" is not locked" + fi + else + l_output2="$l_output2\n - \"automount-open\" is not set so it can not be locked" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + [ -n "$l_pkgoutput" ] && echo -e "\n$l_pkgoutput" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.8.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.8.sh new file mode 100644 index 0000000..f11261a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.8.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" l_output="" l_output2="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" echo -e "$l_pkgoutput" + done + if [ -n "$l_pkgoutput" ]; then + echo -e "$l_pkgoutput" + l_kfile="$(grep -Prils -- '^\h*autorun-never\b' /etc/dconf/db/*.d)" + if [ -f "$l_kfile" ]; then + l_gpname="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<< "$l_kfile")" + fi + if [ -n "$l_gpname" ]; then + l_gpdir="/etc/dconf/db/$l_gpname.d" + if grep -Pq -- "^\h*system-db:$l_gpname\b" /etc/dconf/profile/*; then + l_output="$l_output\n - dconf database profile file \"$(grep -Pl -- "^\h*system-db:$l_gpname\b" /etc/dconf/profile/*)\" exists" + else + l_output2="$l_output2\n - dconf database profile isn't set" + fi + if [ -f "/etc/dconf/db/$l_gpname" ]; then + l_output="$l_output\n - The dconf database \"$l_gpname\" exists" + else + l_output2="$l_output2\n - The dconf database \"$l_gpname\" doesn't exist" + fi + if [ -d "$l_gpdir" ]; then + l_output="$l_output\n - The dconf directory \"$l_gpdir\" exitst" + else + l_output2="$l_output2\n - The dconf directory \"$l_gpdir\" doesn't exist" + fi + if grep -Pqrs -- '^\h*autorun-never\h*=\h*true\b' "$l_kfile"; then + l_output="$l_output\n - \"autorun-never\" is set to true in: \"$l_kfile\"" + else + l_output2="$l_output2\n - \"autorun-never\" is not set correctly" + fi + else + l_output2="$l_output2\n - \"autorun-never\" is not set" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.9.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.9.sh new file mode 100644 index 0000000..4fbf6d3 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/1.8.9.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +{ + l_pkgoutput="" + if command -v dpkg-query > /dev/null 2>&1; then + l_pq="dpkg-query -W" + elif + command -v rpm > /dev/null 2>&1; then + l_pq="rpm -q" + fi + l_pcl="gdm gdm3" + for l_pn in $l_pcl; do + $l_pq "$l_pn" > /dev/null 2>&1 && l_pkgoutput="$l_pkgoutput\n - Package: \"$l_pn\" exists on the system\n - checking configuration" + done + if [ -n "$l_pkgoutput" ]; then + l_output="" l_output2="" + l_kfd="/etc/dconf/db/$(grep -Psril '^\h*autorun-never\b' /etc/dconf/db/*/ | awk -F'/' '{split($(NF-1),a,".");print a[1]}').d" + if [ -d "$l_kfd" ]; then + if grep -Piq '^\h*\/org/gnome\/desktop\/media-handling\/autorun-never\b' "$l_kfd"; then + l_output="$l_output\n - \"autorun-never\" is locked in \"$(grep -Pil '^\h*\/org/gnome\/desktop\/media-handling\/autorun-never\b' "$l_kfd")\"" + else + l_output2="$l_output2\n - \"autorun-never\" is not locked" + fi + else + l_output2="$l_output2\n - \"autorun-never\" is not set so it can not be locked" + fi + else + l_output="$l_output\n - GNOME Desktop Manager package is not installed on the system\n - Recommendation is not applicable" + fi + [ -n "$l_pkgoutput" ] && echo -e "\n$l_pkgoutput" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/2.3.3.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/2.3.3.sh new file mode 100644 index 0000000..00f5eaf --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/2.3.3.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +config_file="/etc/sysconfig/chronyd" + +if [[ ! -f "$config_file" || ! -r "$config_file" ]]; then + echo "Configuration file '$config_file' is missing or not readable. Exiting." + exit 1 +fi + +regex_pattern="^\s*OPTIONS=\s*([^#\n\r]+\s+)?-u\s+root\b" +value="-u\s+root\b" +if grep -Eq "$regex_pattern" "$config_file"; then + echo " \"$value\" in $config_file is found" + exit 1 +else + echo "\"$value\" not found or not set " +fi +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/2.4.18.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/2.4.18.sh new file mode 100644 index 0000000..4692a30 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/2.4.18.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +# Define the files to check +FILES=("/etc/cron.allow" "/etc/cron.deny") + +# Function to check a file +check_file() { + local file=$1 + + # Check if the file exists + if [ ! -e "$file" ]; then + echo "File $file does not exist. Ignoring." + return 0 + fi + + # Get the file permissions in numeric format + local permissions=$(stat -c "%a" "$file") + local owner=$(stat -c "%U" "$file") + local group=$(stat -c "%G" "$file") + + # Check if the file permissions are 0640 or more restrictive + if [ "$permissions" -gt 640 ]; then + echo "File $file permissions are not 0640 or more restrictive." + return 1 + fi + + # Check if the owner is root and group is root + if [ "$owner" != "root" ] || [ "$group" != "root" ]; then + echo "File $file owner or group is not root." + return 1 + fi + + return 0 +} + +# Check each file +for file in "${FILES[@]}"; do + if ! check_file "$file"; then + exit 1 + fi +done + +# If all checks pass, exit with status 0 +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/3.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/3.1.3.sh new file mode 100644 index 0000000..4f2772c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/3.1.3.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" l_mname="tipc" + if [ -z "$(modprobe -n -v "$l_mname" 2>&1 | grep -Pi -- "\h*modprobe:\h+FATAL:\h+Module\h+$l_mname\h+not\h+found\h+in\h+directory")" ]; then + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<< "$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<< "$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<< "$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + if ! lsmod | grep "$l_mname" > /dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + if modprobe --showconfig | grep -Pq -- "^\h*blacklist\h+$l_mname\b"; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi + else + l_output="$l_output\n - Module \"$l_mname\" doesn't exist on the system" + fi + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/4.1.2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/4.1.2.sh new file mode 100644 index 0000000..b8f0893 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/4.1.2.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +{ + l_output="" l_output2="" l_fwd_status="" l_nft_status="" l_fwutil_status="" + rpm -q firewalld > /dev/null 2>&1 && l_fwd_status="$(systemctl is-enabled firewalld.service):$(systemctl is-active firewalld.service)" + rpm -q nftables > /dev/null 2>&1 && l_nft_status="$(systemctl is-enabled nftables.service):$(systemctl is-active nftables.service)" + l_fwutil_status="$l_fwd_status:$l_nft_status" + case $l_fwutil_status in + enabled:active:masked:inactive|enabled:active:disabled:inactive) + l_output="\n - FirewallD utility is in use, enabled and active\n - NFTables utility is correctly disabled or masked and inactive" ;; + masked:inactive:enabled:active|disabled:inactive:enabled:active) + l_output="\n - NFTables utility is in use, enabled and active\n - FirewallD utility is correctly disabled or masked and inactive" ;; + enabled:active:enabled:active) + l_output2="\n - Both FirewallD and NFTables utilities are enabled and active" ;; + enabled:*:enabled:*) l_output2="\n - Both FirewallD and NFTables utilities are enabled" ;; + *:active:*:active) l_output2="\n - Both FirewallD and NFTables utilities are enabled" ;; + :enabled:active) l_output="\n - NFTables utility is in use, enabled, and active\n - FirewallD package is not installed" ;; + :) l_output2="\n - Neither FirewallD or NFTables is installed." ;; + *:*:) l_output2="\n - NFTables package is not installed on the system" ;; + *) l_output2="\n - Unable to determine firewall state" ;; + esac + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Results:\n PASS\n$l_output\n" + else + echo -e "\n- Audit Results:\n FAIL\n$l_output2\n" + fi +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.10.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.10.sh new file mode 100644 index 0000000..89ecb6c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.10.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +parameter_sshd_t=disableforwarding +parameter_sshd_config=DisableForwarding +desired_value=yes + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config; then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + else + exit 1 + + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.11.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.11.sh new file mode 100644 index 0000000..49ee504 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.11.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +parameter_sshd_t=gssapiauthentication +parameter_sshd_config=GSSAPIAuthentication +desired_value=no + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq "^$parameter_sshd_config" /etc/ssh/sshd_config; then + actual_value=$(grep "^$parameter_sshd_config" /etc/ssh/sshd_config | awk '{print $2}') + else + + exit 1 + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.12.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.12.sh new file mode 100644 index 0000000..40eb8e2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.12.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +parameter_sshd_t=hostbasedauthentication +parameter_sshd_config=HostbasedAuthentication +desired_value=no + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq "^$parameter_sshd_config" /etc/ssh/sshd_config; then + actual_value=$(grep "^$parameter_sshd_config" /etc/ssh/sshd_config | awk '{print $2}') + else + exit 1 + + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.13.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.13.sh new file mode 100644 index 0000000..44c53ba --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.13.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +parameter_sshd_t=ignorerhosts +parameter_sshd_config=IgnoreRhosts +desired_value=yes + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config; then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + else + echo "$parameter_sshd_config not set in sshd_config, using default" + actual_value=no + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.14.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.14.sh new file mode 100644 index 0000000..55f58f2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.14.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +#test +parameter_sshd_t=logingracetime +parameter_sshd_config=LoginGraceTime +desired_value=60 + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config; then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + else + echo "$parameter_sshd_config not set in sshd_config, using default" + actual_value=120 + fi +fi + +if [ "$actual_value" -le "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.15.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.15.sh new file mode 100644 index 0000000..90d49f0 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.15.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +parameter_sshd_t=loglevel +parameter_sshd_config=LogLevel +desired_value=INFO +desired_value1=VERBOSE + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq "^$parameter_sshd_config" /etc/ssh/sshd_config; then + actual_value=$(grep "^$parameter_sshd_config" /etc/ssh/sshd_config | awk '{print $2}') + else + echo "$parameter_sshd_config not set in sshd_config, using default" + actual_value=INFO + fi +fi + +if [ "$actual_value" = "$desired_value" ] || [ "$actual_value" = "$desired_value1" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.17.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.17.sh new file mode 100644 index 0000000..e1d2b8d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.17.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +parameter_sshd_t=maxstartups +parameter_sshd_config=MaxStartups +desired_value="10:30:60" + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -Ei "^$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq "^$parameter_sshd_config" /etc/ssh/sshd_config; then + actual_value=$(grep -E "^$parameter_sshd_config" /etc/ssh/sshd_config | awk '{print $2}') + else + echo "$parameter_sshd_config not set in sshd_config, using default" + exit 1 + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.18.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.18.sh new file mode 100644 index 0000000..9d1ac4d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.18.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +parameter_sshd_t=maxsessions +parameter_sshd_config=MaxSessions +FILE="/etc/ssh/sshd_config" +desired_value=10 + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + + if grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config; then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + else + exit 1 + fi +fi + +if [ "$actual_value" -le "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.9.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.9.sh new file mode 100644 index 0000000..c1284aa --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.1.9.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +parameter_sshd_t=clientaliveinterval +parameter_sshd_config=ClientAliveInterval +desired_value=15 + +parameter_sshd_t1=clientalivecountmax +parameter_sshd_config1=ClientAliveCountMax +desired_value1=3 + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') +actual_value1=$(sshd -T | grep -i "$parameter_sshd_t1" | awk '{print $2}') + +if [ -z "$actual_value" ] && [ -z "$actual_value1" ]; then + if (grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config) && (grep -iq '^$parameter_sshd_config1' /etc/ssh/sshd_config); then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + actual_value1=$(grep -i '^$parameter_sshd_config1' /etc/ssh/sshd_config | awk '{print $2}') + + else + echo "$parameter_sshd_config not set in sshd_config, using default" + exit 1 + fi +fi + +if [ "$actual_value" -eq "$desired_value" ] && [ "$actual_value1" -eq "$desired_value1" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.2.sh new file mode 100644 index 0000000..4fe362e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.2.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +# Check if authselect.conf exists +if [[ ! -f /etc/authselect/authselect.conf ]]; then + echo "/etc/authselect/authselect.conf is missing." + exit 1 +fi + +l_module_name="faillock" +l_pam_profile="$(head -1 /etc/authselect/authselect.conf)" + +if grep -Pq -- '^custom\/' <<<"$l_pam_profile"; then + l_pam_profile_path="/etc/authselect/$l_pam_profile" +else + l_pam_profile_path="/usr/share/authselect/default/$l_pam_profile" +fi + +for file in "$l_pam_profile_path/password-auth" "$l_pam_profile_path/system-auth"; do + if [[ ! -f "$file" ]]; then + echo "File $file does not exist. Test failed." + exit 1 + fi + + if ! grep -P -- "\bpam_$l_module_name\.so\b" "$file" >/dev/null; then + echo "pam_faillock.so entry not found in $file. Test failed." + exit 1 + else + echo "pam_faillock.so entry found in $file." + fi + + if ! grep -P -- "\{include if \"with-faillock\"\}" "$file" >/dev/null; then + echo "Entry '{include if \"with-faillock\"}' not found in $file. Test failed." + exit 1 + else + echo "Entry '{include if \"with-faillock\"}' found in $file. Test passed." + fi +done + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.3.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.3.sh new file mode 100644 index 0000000..d2298f0 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.3.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +# Check if /etc/authselect/authselect.conf exists +if [[ ! -f /etc/authselect/authselect.conf ]]; then + echo "/etc/authselect/authselect.conf is missing." + exit 1 +fi + +l_module_name="unix" +l_pam_profile="$(head -1 /etc/authselect/authselect.conf)" + +if grep -Pq -- '^custom\/' <<<"$l_pam_profile"; then + l_pam_profile_path="/etc/authselect/$l_pam_profile" +else + l_pam_profile_path="/usr/share/authselect/default/$l_pam_profile" +fi + +for file in "$l_pam_profile_path/password-auth" "$l_pam_profile_path/system-auth"; do + if [[ ! -f "$file" ]]; then + echo "File $file does not exist. Test failed." + exit 1 + fi + + if ! grep -P -- "\bpam_$l_module_name\.so\b" "$file" >/dev/null; then + echo "pam_unix.so entry not found in $file. Test failed." + exit 1 + else + echo "pam_unix.so entry found in $file. Test passed." + fi +done + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.4.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.4.sh new file mode 100644 index 0000000..e9278ab --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.4.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +# Check if authselect.conf exists +if [[ ! -f /etc/authselect/authselect.conf ]]; then + echo "/etc/authselect/authselect.conf is missing." + exit 1 +fi + +l_module_name="pwhistory" +l_pam_profile="$(head -1 /etc/authselect/authselect.conf)" + +# Check if authselect.conf exists +if [[ ! -f /etc/authselect/authselect.conf ]]; then + echo "/etc/authselect/authselect.conf is missing." + exit 0 +fi + +if grep -Pq -- '^custom\/' <<<"$l_pam_profile"; then + l_pam_profile_path="/etc/authselect/$l_pam_profile" +else + l_pam_profile_path="/usr/share/authselect/default/$l_pam_profile" +fi + +for file in "$l_pam_profile_path/password-auth" "$l_pam_profile_path/system-auth"; do + if [[ ! -f "$file" ]]; then + echo "File $file does not exist. Test failed." + exit 1 + fi + + if ! grep -P -- "\bpam_$l_module_name\.so\b" "$file" >/dev/null; then + echo "pam_pwhistory.so entry not found in $file. Test failed." + exit 1 + else + echo "pam_pwhistory.so entry found in $file." + fi + + if ! grep -P -- "\{include if \"with-pwhistory\"\}" "$file" >/dev/null; then + echo "Entry '{include if \"with-pwhistory\"}' not found in $file. Test failed." + exit 1 + else + echo "Entry '{include if \"with-pwhistory\"}' found in $file. Test passed." + fi +done + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.5.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.5.sh new file mode 100644 index 0000000..d6b0db9 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.2.5.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +# Check if authselect.conf exists +if [[ ! -f /etc/authselect/authselect.conf ]]; then + echo "/etc/authselect/authselect.conf is missing." + exit 1 +fi + +l_module_name="unix" +l_pam_profile="$(head -1 /etc/authselect/authselect.conf)" + +if grep -Pq -- '^custom\/' <<<"$l_pam_profile"; then + l_pam_profile_path="/etc/authselect/$l_pam_profile" +else + l_pam_profile_path="/usr/share/authselect/default/$l_pam_profile" +fi + +for file in "$l_pam_profile_path/password-auth" "$l_pam_profile_path/system-auth"; do + if [[ ! -f "$file" ]]; then + echo "File $file does not exist. Test failed." + exit 1 + fi + if ! grep -P -- "\bpam_$l_module_name\.so\b" "$file" >/dev/null; then + echo "pam_unix.so entry not found in $file. Test failed." + exit 1 + else + echo "pam_unix.so entry found in $file. Test passed." + fi +done + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.2.7.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.2.7.sh new file mode 100644 index 0000000..ed6605d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.2.7.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# File configuration +FILE="/etc/security/pwquality.conf" +# what we look for +PATTERN="enforce_for_root" + +# Check if the file exists +if [ ! -f "$FILE" ]; then + echo "File $FILE wa not found." + exit 1 +fi + +# Search for the pattern, regardless of its case, even if it is commented out +grep -Ei "^[[:space:]]*#?[[:space:]]*$PATTERN" "$FILE" >/dev/null +FOUND=$? + +# if the pattern is found +if [ $FOUND -eq 0 ]; then + # check if it is commented + grep -Ei "^[[:space:]]*#[[:space:]]*$PATTERN" "$FILE" >/dev/null + COMMENTED=$? + + if [ $COMMENTED -eq 0 ]; then + exit 1 + fi + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.3.1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.3.1.sh new file mode 100644 index 0000000..ba6dc49 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.3.1.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +pw_file="/etc/security/pwhistory.conf" +value="remember" +regex_pattern="^\s*${value}\s*=\s*[0-9]+\s*$" +expected_value=24 +if grep -Eq "$regex_pattern" "$pw_file"; then + current_value=$(grep -Eo "$regex_pattern" "$pw_file" | awk -F'=' '{print $2}' | tr -d ' ') + if ((current_value < expected_value)); then + echo "ERROR: $value = $current_value < $expected_value" + exit 1 + else + echo "$value = $current_value > $expected_value" + exit 0 + fi +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.3.2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.3.2.sh new file mode 100644 index 0000000..b90f820 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.3.2.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +pw_file="/etc/security/pwhistory.conf" + +value="enfore_for_root" + +regex_pattern="^\s*#*\s*${value}\s*" + +if grep -Eq "^\s*${value}\s*$" "$pw_file"; then + echo "$value is correctly set." + exit 0 +else + echo "ERROR: $value is either missing or commented out." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.4.2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.4.2.sh new file mode 100644 index 0000000..c634d6a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.4.2.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +if [[ ! -d "/etc/authselect" && ! -d "/usr/share/authselect" ]]; then + echo "Authselect is not installed. Exiting." + exit 1 +fi + +pam_profile="$(head -1 /etc/authselect/authselect.conf 2>/dev/null || echo "default")" + +if [[ "$pam_profile" =~ ^custom/ ]]; then + pam_profile_path="/etc/authselect/$pam_profile" +else + pam_profile_path="/usr/share/authselect/default/$pam_profile" +fi + +for auth_file in "$pam_profile_path"/{password-auth,system-auth}; do + if grep -Eq '^\s*password\s+([^#\n\r]+\s+)?pam_unix\.so\b' $auth_file | grep -Pv '\bremember=\d\b'; then + echo "- \"remember\" is set in $auth_file" + exit 1 + else + echo "- \"remember\" is not set in $auth_file" + fi +done +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.4.3.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.4.3.sh new file mode 100644 index 0000000..87954a6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.3.3.4.3.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +config_file="/etc/authselect/authselect.conf" +if [[ ! -f "$config_file" || ! -r "$config_file" ]]; then + echo "Configuration file '$config_file' is missing or not readable. Exiting." + exit 1 +fi + +if command -v authselect &>/dev/null; then + pam_profile="$(head -1 /etc/authselect/authselect.conf 2>/dev/null || echo "default")" + + if [[ "$pam_profile" =~ ^custom/ ]]; then + pam_profile_path="/etc/authselect/$pam_profile" + else + pam_profile_path="/usr/share/authselect/default/$pam_profile" + fi +else + pam_profile_path="/etc/pam.d" +fi + +for auth_file in "$pam_profile_path"/{password-auth,system-auth}; do + if grep -Eq '^\s*password\s+[^#]*pam_unix\.so\s+.*(sha512|yescrypt)\b' $auth_file; then + echo "- strong password hashing algorithm is set in $auth_file" + else + echo "- strong password hashing algorithm is not set in $auth_file" + exit 1 + fi +done +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.4.1.6.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.4.1.6.sh new file mode 100644 index 0000000..5faf665 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.4.1.6.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +{ + awk -F: '/^[^:]+:[^!*]/{print $1}' /etc/shadow | while read -r usr; do + change=$(date -d "$(chage --list $usr | grep '^Last password change' | cut -d: -f2 | grep -v 'never$')" +%s); + if [[ "$change" -gt "$(date +%s)" ]]; then + echo "User: \"$usr\" last password change was \"$(chage --list $usr | grep '^Last password change' | cut -d: -f2)\""; + fi; + done +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.4.2.1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.4.2.1.sh new file mode 100644 index 0000000..14b6a5b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.4.2.1.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + awk -F: '($3 == 0) { print $1 }' /etc/passwd +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.4.2.5.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.4.2.5.sh new file mode 100644 index 0000000..3ef3663 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/5.4.2.5.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +{ + RPCV="$(sudo -Hiu root env | grep '^PATH' | cut -d= -f2)" + echo "$RPCV" | grep -q "::" && echo "root's path contains a empty directory (::)" + echo "$RPCV" | grep -q ":$" && echo "root's path contains a trailing (:)" + for x in $(echo "$RPCV" | tr ":" " "); do + if [ -d "$x" ]; then + ls -ldH "$x" | awk '$9 == "." {print "PATH contains current working directory (.)"} + $3 != "root" {print $9, "is not owned by root"} + substr($1,6,1) != "-" {print $9, "is group writable"} + substr($1,9,1) != "-" {print $9, "is world writable"}' + else + echo "$x is not a directory" + fi + done +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.1.4.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.1.4.sh new file mode 100644 index 0000000..527ebb6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.1.4.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +socket_installed=$(systemctl list-unit-files | grep -q 'systemd-journal-remote.socket' && echo true || echo false) +service_installed=$(systemctl list-unit-files | grep -q 'systemd-journal-remote.service' && echo true || echo false) + +if [[ "$socket_installed" == "false" && "$service_installed" == "false" ]]; then + exit 0 # True if neither is installed +elif [[ "$socket_installed" == "true" && "$(systemctl is-active systemd-journal-remote.socket)" =~ ^(inactive|failed)$ ]] && + [[ "$service_installed" == "true" && "$(systemctl is-active systemd-journal-remote.service)" =~ ^(inactive|failed)$ ]]; then + exit 0 # True if both are not active (including failed) +else + exit 1 # False otherwise +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.2.sh new file mode 100644 index 0000000..375bb76 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.2.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +regex_pattern="^\s*ForwardToSyslog\s*=\s*no" +config_files=("/etc/systemd/journald.conf" "/etc/systemd/journald.conf.d/*") + +for config_file in "${config_files[@]}"; do + for file in $config_file; do + if [[ -f "$file" ]]; then + if grep -qE "$regex_pattern" "$file"; then + exit 0 + fi + fi + done +done + +exit 1 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.3.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.3.sh new file mode 100644 index 0000000..ac47dad --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.3.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +regex_pattern="^\s*Compress\s*=\s*yes" +config_files=("/etc/systemd/journald.conf" "/etc/systemd/journald.conf.d/*") + +for config_file in "${config_files[@]}"; do + for file in $config_file; do + if [[ -f "$file" ]]; then + if grep -qE "$regex_pattern" "$file"; then + exit 0 + fi + fi + done +done + +exit 1 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.4.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.4.sh new file mode 100644 index 0000000..d2f60bc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.2.4.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +regex_pattern="^\s*Storage\s*=\s*persistent" +config_files=("/etc/systemd/journald.conf" "/etc/systemd/journald.conf.d/*") + +for config_file in "${config_files[@]}"; do + for file in $config_file; do + if [[ -f "$file" ]]; then + if grep -qE "$regex_pattern" "$file"; then + exit 0 + fi + fi + done +done + +exit 1 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.3.4.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.3.4.sh new file mode 100644 index 0000000..3fbba0a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.3.4.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +config_files=("/etc/rsyslog.conf" "/etc/rsyslog.d/*.conf") +expected_value=0640 + +for file in ${config_files[@]}; do + for i in $file; do + if grep -qE '^\s*\$FileCreateMode' "$i" 2>/dev/null; then + chosen_file=$i + fi + done +done +if [[ -n $chosen_file ]]; then + current_value=$(grep -E '^\s*\$FileCreateMode' "$chosen_file" | sed -E 's/^\s*\$FileCreateMode\s+//') + if [[ -n $current_value && $current_value -le $expected_value ]]; then + echo "FileCreateMode is restricted enough" + exit 0 + else + echo "FileCreateMode is not restricted enough" + exit 1 + fi +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.3.7.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.3.7.sh new file mode 100644 index 0000000..31d3bee --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.2.3.7.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +config_files=("/etc/rsyslog.conf" "/etc/rsyslog.d/*.conf") + +for file in "${config_files[@]}"; do + for i in $file; do + if [[ -f $i ]]; then + if grep -qoE '^\s*module\(load="imtcp"\)' "$i" 2>/dev/null; then + exit 1 + fi + if grep -qoE '^\s*input\(type="imtcp"\s+port="[0-9]+"\)' "$i" 2>/dev/null; then + exit 1 + fi + if grep -qoE '^\s*\$ModLoad\s+imtcp' "$i" 2>/dev/null; then + exit 1 + fi + if grep -qoE '^\s*\$InputTCPServerRun' "$i" 2>/dev/null; then + exit 1 + fi + fi + done +done +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.1.2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.1.2.sh new file mode 100644 index 0000000..7b3479d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.1.2.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +GRUB_CFG="/etc/default/grub" + +if [[ ! -f "$GRUB_CFG" ]]; then + echo "Error: $GRUB_CFG does not exist." + exit 1 +fi +if grep -q "audit=1" "$GRUB_CFG"; then + echo "Found 'audit=1' in $GRUB_CFG." + exit 0 +else + echo "'audit=1' not found in $GRUB_CFG." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.1.3.sh new file mode 100644 index 0000000..158b8cc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.1.3.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +GRUB_CFG="/etc/default/grub" + +if [[ ! -f "$GRUB_CFG" ]]; then + echo "Error: $GRUB_CFG does not exist." + exit 1 +fi +if grep -q "audit_backlog_limit" "$GRUB_CFG"; then + echo "Found 'audit_backlog_limit=1' in $GRUB_CFG." + exit 0 +else + echo "'audit_backlog_limit=1' not found in $GRUB_CFG." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.1.sh new file mode 100644 index 0000000..dc826da --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.1.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +perm_mask="0027" +if [ -e "/etc/audit/auditd.conf" ]; then + log_dir="$(dirname "$(awk -F= '/^\s*log_file\s*/{print $2}' /etc/audit/auditd.conf | xargs)")" + if [ -d "$log_dir" ]; then + maxperm="$(printf '%o' $((0777 & ~$perm_mask)))" + log_dir_mode="$(stat -Lc '%#a' "$log_dir")" + if [ $(($log_dir_mode & $perm_mask)) -gt 0 ]; then + exit 1 + fi + else + exit 1 + fi +else + exit 1 +fi +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.2.sh new file mode 100644 index 0000000..a8027ab --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.2.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +l_perm_mask="0137" +if [ -e "/etc/audit/auditd.conf" ]; then + # Extract the log directory from the configuration file + l_audit_log_directory="$(dirname "$(awk -F= '/^\s*log_file\s*/{print $2}' /etc/audit/auditd.conf | xargs)")" + + if [ -d "$l_audit_log_directory" ]; then + l_maxperm="$(printf '%o' $((0777 & ~$l_perm_mask)))" + + # Find files matching the permission mask and process them line by line + while IFS= read -r l_file; do + # Ensure the file exists and get its mode + if [ -e "$l_file" ]; then + l_file_mode="$(stat -Lc '%#a' "$l_file")" + exit 1 + fi + done < <(find "$l_audit_log_directory" -maxdepth 1 -type f -perm /"$l_perm_mask") + + # Check if any files were processed + if [ $? -eq 0 ]; then + exit 0 + fi + else + exit 0 + fi +else + exit 0 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.3.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.3.sh new file mode 100644 index 0000000..9bf99dc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.3.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +l_output="" l_output2="" +if [ -e "/etc/audit/auditd.conf" ]; then + l_audit_log_directory="$(dirname "$(awk -F= '/^\s*log_file\s*/{print $2}' /etc/audit/auditd.conf | xargs)")" + if [ -d "$l_audit_log_directory" ]; then + while IFS= read -r l_file; do + l_output2="$l_output2\n - File: \"$l_file\" is owned by user: \"$(stat -Lc '%U' "$l_file")\"\n (should be owned by user: \"root\")\n" + done < <(find "$l_audit_log_directory" -maxdepth 1 -type f ! -user root) + else + l_output2="$l_output2\n - Log file directory not set in \"/etc/audit/auditd.conf\" please set log file directory" + fi +else + l_output2="$l_output2\n - File: \"/etc/audit/auditd.conf\" not found.\n - ** Verify auditd is installed **" +fi +if [ -z "$l_output2" ]; then + l_output="$l_output\n - All files in \"$l_audit_log_directory\" are owned by user: \"root\"\n" + echo -e "\n- Audit Result:\n ** PASS **\n - * Correctly configured * :$l_output" + exit 0 +else + echo -e "\n- Audit Result:\n ** FAIL **\n - * Reasons for auditgfailure * :$l_output2\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.4.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.4.sh new file mode 100644 index 0000000..b5e03bd --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/6.3.4.4.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +audit_conf="/etc/audit/auditd.conf" +perm_mask="0177" +if [ ! -f "$audit_conf" ]; then + exit 1 +fi +audit_log_dir=$(grep -E '^\s*log_file\s*=' "$audit_conf" | cut -d= -f2 | xargs dirname 2>/dev/null) +if [ -z "$audit_log_dir" ]; then + exit 1 +fi +audit_log_group=$(grep -E '^\s*log_group\s*=' "$audit_conf" | cut -d= -f2 | xargs) +if [ -z "$audit_log_group" ]; then + exit 1 +fi +if [ ! -d "$audit_log_dir" ]; then + exit 1 +fi +for file in "$audit_log_dir"/*; do + if [ -f "$file" ]; then + group=$(ls -l "$file" | awk '{print $4}') + if [[ "$group" != "root" && "$group" != "adm" ]]; then + exit 1 + fi + fi +done +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/7.2.1.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/7.2.1.sh new file mode 100644 index 0000000..8a41221 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/7.2.1.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + awk -F: '($2 != "x" ) { print $1 " is not set to shadowed passwords "}' /etc/passwd +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/7.2.2.sh b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/7.2.2.sh new file mode 100644 index 0000000..2e5e69e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/RHEL9_CIS2.0.0/7.2.2.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +{ + awk -F: '($2 == "" ) { print $1 " does not have a password "}' /etc/shadow +} \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-1.8.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-1.8.1.3.sh new file mode 100644 index 0000000..9e530cc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-1.8.1.3.sh @@ -0,0 +1,2 @@ +#!/bin/bash +grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue.net \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-5.4.2_1.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-5.4.2_1.sh new file mode 100644 index 0000000..47785d8 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-5.4.2_1.sh @@ -0,0 +1,2 @@ +#!/bin/bash +awk -F: '($1!="root" && $1!="sync" && $1!="shutdown" && $1!="halt" && $1!~/^\+/ && $3<'"$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)"' && $7!="'"$(which nologin)"'" && $7!="/bin/false") {print}' /etc/passwd \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-5.4.2_2.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-5.4.2_2.sh new file mode 100644 index 0000000..af16149 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-5.4.2_2.sh @@ -0,0 +1,2 @@ +#!/bin/bash +awk -F: '($1!="root" && $1!~/^\+/ && $3<'"$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)"') {print $1}' /etc/passwd | xargs -I '{}' passwd -S '{}' | awk '($2!="L" && $2!="LK") {print $1}' \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-5.4.4.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-5.4.4.sh new file mode 100644 index 0000000..21cdbfc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-5.4.4.sh @@ -0,0 +1,4 @@ +#!/bin/bash +for f in /etc/profile.d/*.sh ; do + grep -Eq '(^|^[^#]*;)\s*(readonly|export(\s+[^$#;]+\s*)*)?\s*TMOUT=(900|[1-8][0-9][0-9]|[1-9][0-9]|[1-9])\b' $f && grep -Eq '(^|^[^#]*;)\s*readonly\s+TMOUT\b' $f && grep -Eq '(^|^[^#]*;)\s*export\s+([^$#;]+\s+)*TMOUT\b' $f && echo "TMOUT correctly configured in file: $f"; +done \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.1.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.1.sh new file mode 100644 index 0000000..38c459d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.1.sh @@ -0,0 +1,2 @@ +#!/bin/bash +awk -F: '($2 != "x" ) { print $1 " is not set to shadowed passwords "}' /etc/passwd \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.10.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.10.sh new file mode 100644 index 0000000..bbd8860 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.10.sh @@ -0,0 +1,10 @@ +#!/bin/bash +awk -F: '($1 !~ /^(root|halt|sync|shutdown)$/ && $7 != "'"$(which nologin)"'" && $7 != "/bin/false" && $7 != "/usr/bin/false") { print $1 " " $6 }' /etc/passwd | while read user dir; do + if [ ! -d "$dir" ]; then + echo "The home directory ($dir) of user $user does not exist." + else + if [ ! -h "$dir/.netrc" -a -f "$dir/.netrc" ]; then + echo ".netrc file $dir/.netrc exists" + fi + fi +done \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.11.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.11.sh new file mode 100644 index 0000000..118123e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.11.sh @@ -0,0 +1,30 @@ +#!/bin/bash +awk -F: '($1 !~ /^(root|halt|sync|shutdown)$/ && $7 != "'"$(which nologin)"'" && $7 != "/bin/false" && $7 != "/usr/bin/false") { print $1 " " $6 }' /etc/passwd | while read user dir; do + if [ ! -d "$dir" ]; then + echo "The home directory ($dir) of user $user does not exist." + else + for file in $dir/.netrc; do + if [ ! -h "$file" -a -f "$file" ]; then + fileperm=$(ls -ld $file | cut -f1 -d" ") + if [ $(echo $fileperm | cut -c5) != "-" ]; then + echo "Group Read set on $file" + fi + if [ $(echo $fileperm | cut -c6) != "-" ]; then + echo "Group Write set on $file" + fi + if [ $(echo $fileperm | cut -c7) != "-" ]; then + echo "Group Execute set on $file" + fi + if [ $(echo $fileperm | cut -c8) != "-" ]; then + echo "Other Read set on $file" + fi + if [ $(echo $fileperm | cut -c9) != "-" ]; then + echo "Other Write set on $file" + fi + if [ $(echo $fileperm | cut -c10) != "-" ]; then + echo "Other Execute set on $file" + fi + fi + done + fi +done \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.12.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.12.sh new file mode 100644 index 0000000..685a0d0 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.12.sh @@ -0,0 +1,12 @@ +#!/bin/bash +awk -F: '($1 !~ /^(root|halt|sync|shutdown)$/ && $7 != "'"$(which nologin)"'" && $7 != "/bin/false" && $7 != "/usr/bin/false") { print $1 " " $6 }' /etc/passwd | while read user dir; do + if [ ! -d "$dir" ]; then + echo "The home directory ($dir) of user $user does not exist." + else + for file in $dir/.rhosts; do + if [ ! -h "$file" -a -e "$file" ]; then + echo ".rhosts file in $dir" + fi + done + fi +done \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.18_1.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.18_1.sh new file mode 100644 index 0000000..810e325 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.18_1.sh @@ -0,0 +1,2 @@ +#!/bin/bash +grep ^shadow:[^:]*:[^:]*:[^:]+ /etc/group \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.18_2.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.18_2.sh new file mode 100644 index 0000000..ab4d48a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.18_2.sh @@ -0,0 +1,2 @@ +#!/bin/bash +awk -F: '($4 == "") { print }' /etc/passwd \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.2.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.2.sh new file mode 100644 index 0000000..5e6b3c3 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.2.sh @@ -0,0 +1,2 @@ +#!/bin/bash +awk -F: '($2 == "" ) { print $1 " does not have a password "}' /etc/shadow \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.5.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.5.sh new file mode 100644 index 0000000..ef0dc08 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.5.sh @@ -0,0 +1,6 @@ +#!/bin/bash +grep -E -v '^(halt|sync|shutdown)' /etc/passwd | awk -F: '($7 != "'"$(which nologin)"'" && $7 != "/bin/false") { print $1 " " $6 }' | while read -r user dir; do + if [ ! -d "$dir" ]; then + echo "The home directory ($dir) of user $user does not exist." + fi +done \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.6.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.6.sh new file mode 100644 index 0000000..9d14223 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.6.sh @@ -0,0 +1,20 @@ +#!/bin/bash +grep -E -v '^(halt|sync|shutdown)' /etc/passwd | awk -F: '($7 != "'"$(which nologin)"'" && $7 != "/bin/false") { print $1 " " $6 }' | while read user dir; do + if [ ! -d "$dir" ]; then + echo "The home directory ($dir) of user $user does not exist." + else + dirperm=$(ls -ld $dir | cut -f1 -d" ") + if [ $(echo $dirperm | cut -c6) != "-" ]; then + echo "Group Write permission set on the home directory ($dir) of user $user" + fi + if [ $(echo $dirperm | cut -c8) != "-" ]; then + echo "Other Read permission set on the home directory ($dir) of user $user" + fi + if [ $(echo $dirperm | cut -c9) != "-" ]; then + echo "Other Write permission set on the home directory ($dir) of user $user" + fi + if [ $(echo $dirperm | cut -c10) != "-" ]; then + echo "Other Execute permission set on the home directory ($dir) of user $user" + fi + fi +done \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.7.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.7.sh new file mode 100644 index 0000000..4df7421 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.7.sh @@ -0,0 +1,11 @@ +#!/bin/bash +grep -E -v '^(halt|sync|shutdown)' /etc/passwd | awk -F: '($7 != "'"$(which nologin)"'" && $7 != "/bin/false") { print $1 " " $6 }' | while read user dir; do + if [ ! -d "$dir" ]; then + echo "The home directory ($dir) of user $user does not exist." + else + owner=$(stat -L -c "%U" "$dir") + if [ "$owner" != "$user" ]; then + echo "The home directory ($dir) of user $user is owned by $owner." + fi + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.8.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.8.sh new file mode 100644 index 0000000..01e4ddc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.8.sh @@ -0,0 +1,18 @@ +#!/bin/bash +grep -E -v '^(halt|sync|shutdown)' /etc/passwd | awk -F: '($7 != "'"$(which nologin)"'" && $7 != "/bin/false") { print $1 " " $6 }' | while read user dir; do + if [ ! -d "$dir" ]; then + echo "The home directory ($dir) of user $user does not exist." + else + for file in $dir/.[A-Za-z0-9]*; do + if [ ! -h "$file" -a -f "$file" ]; then + fileperm=$(ls -ld $file | cut -f1 -d" ") + if [ $(echo $fileperm | cut -c6) != "-" ]; then + echo "Group Write permission set on file $file" + fi + if [ $(echo $fileperm | cut -c9) != "-" ]; then + echo "Other Write permission set on file $file" + fi + fi + done + fi +done \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.9.sh b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.9.sh new file mode 100644 index 0000000..113a2ce --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/SLE_15/CIS-SEL15-6.2.9.sh @@ -0,0 +1,10 @@ +#!/bin/bash +awk -F: '($1 !~ /^(root|halt|sync|shutdown)$/ && $7 != "'"$(which nologin)"'" && $7 != "/bin/false" && $7 != "/usr/bin/false") { print $1 " " $6 }' /etc/passwd | while read user dir; do + if [ ! -d "$dir" ] ; then + echo "The home directory ($dir) of user $user does not exist." + else + if [ ! -h "$dir/.forward" -a -f "$dir/.forward" ]; then + echo ".forward file $dir/.forward exists" + fi + fi +done \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.1.2.2.1.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.1.2.2.1.sh new file mode 100644 index 0000000..88fc6ec --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.1.2.2.1.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +CHECK_DIR="/dev/shm" +findmnt -kn "$CHECK_DIR" &>/dev/null +exit $? \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.3.1.2.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.3.1.2.sh new file mode 100644 index 0000000..7d7d905 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.3.1.2.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +GRUB_CFG="/etc/default/grub" + +if [[ ! -f "$GRUB_CFG" ]]; then + echo "Error: $GRUB_CFG does not exist." + exit 1 +fi +if grep -q "apparmor=1" "$GRUB_CFG"; then + echo "Found 'apparmor=1' in $GRUB_CFG." + exit 0 +else + echo "'apparmor=1' not found in $GRUB_CFG." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.3.1.4.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.3.1.4.sh new file mode 100644 index 0000000..c4344c4 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.3.1.4.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +unconfined_lines=$(apparmor_status | grep unconfined) + +while IFS= read -r line; do + if [[ ! "$line" =~ ^0 ]]; then + exit 1 + fi +done <<<"$unconfined_lines" +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.5.3.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.5.3.sh new file mode 100644 index 0000000..5895ecc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.5.3.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +kernel_parameters=("fs.suid_dumpable") +kernel_values=("0") +len=${#kernel_parameters[@]} +for ((i = 0; i < len; i++)); do + param=${kernel_parameters[$i]} + value=${kernel_values[$i]} + current_value=$(sysctl -n "$param" 2>/dev/null) + + # Check if sysctl command was successful + if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $param does not exist or could not be retrieved." + exit 1 + fi + + # Check if the current value matches the expected value + if [ "$current_value" == "$value" ]; then + echo "Kernel parameter $param is set correctly to $value." + else + echo "Kernel parameter $param is not set to $value (current value: $current_value)." + exit 1 + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.6.1.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.6.1.sh new file mode 100644 index 0000000..373e1cc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.6.1.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# Extract the OS ID from /etc/os-release +OS_ID=$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g') + +# Run the grep command with the OS ID incorporated +grep -Eis "(\\v|\\r|\\m|\\s|$OS_ID)" /etc/motd + +# Check the exit code of the grep command +if [ $? -ne 0 ]; then + # Grep did not find any matches, return 0 + exit 0 +else + # Grep found matches, return 1 + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.6.4.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.6.4.sh new file mode 100644 index 0000000..a2766e2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.6.4.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +TEST_FILE="/etc/motd" +if [ -e "$TEST_FILE" ]; then + DESIRED_PERM="644" + ACTUAL_PERM=$(stat -c "%a" "$TEST_FILE") + if [[ "$ACTUAL_PERM" == "$DESIRED_PERM" ]]; then + exit 0 + else + exit 1 + fi +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.7.10.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.7.10.sh new file mode 100644 index 0000000..d21b15d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.7.10.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +config_file="/etc/gdm/custom.conf" + +if [[ ! -f "$config_file" || ! -r "$config_file" ]]; then + exit 0 +fi + +value="Enable" + +if grep -Eq "^\s*$value\s*=\s*true\s*$" "$config_file"; then + echo -e " \"$value\" in $config_file is true" + exit 1 +else + echo -e "\"$value\" not found or not set " +fi +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.2.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.2.sh new file mode 100644 index 0000000..9be133e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.2.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" +elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" +fi + +found=1 +for gdm in "gdm" "gdm3"; do # Space seporated list of packages to check + $l_pq $gdm &>/dev/null && found=0 +done + +if [[ $found -eq 0 ]]; then + l_gdmfile="$(grep -Prils '^\h*banner-message-enable\b' /etc/dconf/db/*.d)" # can be multipale + num_gdmfile=$(wc -l <<< $l_gdmfile) + if [[ -n "$l_gdmfile" ]]; then + # wc -l because all files need to be set to true; grep -q states min 1 file is set to true + [[ $(grep -Pisl '^\h*banner-message-enable\h*=\h*true\b' $l_gdmfile | wc -l) < $num_gdmfile ]] && exit 1 + [[ $(grep -Pisl '^\h*banner-message-text\h*=\h*.*$' $l_gdmfile | wc -l) < $num_gdmfile ]] && exit 1 + l_gdmprofile="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<<"$l_gdmfile")" # can be multipale + for prof in $l_gdmprofile; do + # -r because local db config rules etc. can be listet under /etc/dconf/profile/user or others + grep -Prq "^\h*system-db:$prof" /etc/dconf/profile/ || exit 1 + [ -f "/etc/dconf/db/$prof" ] || exit 1 + done + else + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.3.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.3.sh new file mode 100644 index 0000000..4e9ecf2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.3.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" +elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" +fi + +found=1 +for gdm in "gdm" "gdm3"; do # Space seporated list of packages to check + $l_pq $gdm &>/dev/null && found=0 +done + +if [[ $found -eq 0 ]]; then + l_gdmfile="$(grep -Prils '^\h*disable-user-list\h*=\h*true\b' /etc/dconf/db/*.d)" # can be multipale + if [[ -n "$l_gdmfile" ]]; then + l_gdmprofile="$(awk -F\/ '{split($(NF-1),a,".");print a[1]}' <<<"$l_gdmfile")" # can be multipale + for prof in $l_gdmprofile; do + # -r because local db config rules etc. can be listet under /etc/dconf/profile/user or others + grep -Prq "^\h*system-db:$prof" /etc/dconf/profile/ || exit 1 + [ -f "/etc/dconf/db/$prof" ] || exit 1 + done + else + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.4.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.4.sh new file mode 100644 index 0000000..aef3c5e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.4.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# untested - changed settings don't take effect?! + +max_lockdelay=5 +max_idledelay=900 + +unit_lockdelay=$(gsettings get org.gnome.desktop.screensaver lock-delay 2>/dev/null) +unit_idledelay=$(gsettings get org.gnome.desktop.session idle-delay 2>/dev/null) + +if [[ -n "$unit_lockdelay" && -n "$unit_idledelay" ]]; then # is gnome installed + idledelay=$(cut -d ' ' -f 2 <<<"$unit_idledelay") + + [[ $idledelay -gt $max_idledelay || $idledelay -le 0 ]] && exit 1 + [[ $(cut -d ' ' -f 2 <<<"$unit_lockdelay") -gt $max_lockdelay ]] && exit 1 +fi + +exit 0 \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.5.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.5.sh new file mode 100644 index 0000000..1be9483 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.5.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" +elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" +fi + +found=1 +for gdm in "gdm" "gdm3"; do # Space seporated list of packages to check + $l_pq $gdm &>/dev/null && found=0 +done + +checkLock() { + l_gdmfile="$(grep -Prils "^\h*$1\h*=\h*\d+\b" /etc/dconf/db/*.d)" # can be multipale + if [[ -n "$l_gdmfile" ]]; then + for path in $(dirname $l_gdmfile); do + grep -Prisq "^\h*\/org\/gnome\/desktop\/$2\/$1\b" "$path/locks" || exit 1 + done + else + exit 1 + fi +} + +if [[ $found -eq 0 ]]; then + checkLock "idle-delay" "session" + checkLock "lock-delay" "screensaver" +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.6.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.6.sh new file mode 100644 index 0000000..1a65199 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.6.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +auto=$(gsettings get org.gnome.desktop.media-handling automount 2>/dev/null) +# -n checks for gnome installed +[[ -n "$auto" && "$auto" != "false" ]] && exit 1 + +autOpen=$(gsettings get org.gnome.desktop.media-handling automoun-open 2>/dev/null) +[[ -n "$autOpen" && "$autOpen" != "false" ]] && exit 1 + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.7.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.7.sh new file mode 100644 index 0000000..99cd926 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.7.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" +elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" +fi + +found=1 +for gdm in "gdm" "gdm3"; do # Space seporated list of packages to check + $l_pq $gdm &>/dev/null && found=0 +done + +checkLock() { + l_gdmfile="$(grep -Prils "^\h*$1\h*=\h*\w+\b" /etc/dconf/db/*.d)" # can be multipale + if [[ -n "$l_gdmfile" ]]; then + for path in $(dirname $l_gdmfile); do + grep -Prisq "^\h*\/org\/gnome\/desktop\/media-handling\/$1\b" "$path/locks" || exit 1 + done + else + exit 1 + fi +} + +if [[ $found -eq 0 ]]; then + checkLock "automount" + checkLock "automount-open" +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.8.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.8.sh new file mode 100644 index 0000000..6ff5147 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.8.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +auto=$(gsettings get org.gnome.desktop.media-handling autorun-never 2>/dev/null) +# -n checks for gnome installed +[[ -n "$auto" && "$auto" != "true" ]] && exit 1 + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.9.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.9.sh new file mode 100644 index 0000000..1eb2760 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/1.8.9.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +if command -v dpkg-query >/dev/null 2>&1; then + l_pq="dpkg-query -W" +elif command -v rpm >/dev/null 2>&1; then + l_pq="rpm -q" +fi + +found=1 +for gdm in "gdm" "gdm3"; do # Space seporated list of packages to check + $l_pq $gdm &>/dev/null && found=0 +done + +checkLock() { + l_gdmfile="$(grep -Prils "^\h*$1\h*=\h*\w+\b" /etc/dconf/db/*.d)" # can be multipale + if [[ -n "$l_gdmfile" ]]; then + for path in $(dirname $l_gdmfile); do + grep -Prisq "^\h*\/org\/gnome\/desktop\/media-handling\/$1\b" "$path/locks" || exit 1 + done + else + exit 1 + fi +} + +if [[ $found -eq 0 ]]; then + checkLock "autorun-never" +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/2.1.1.1.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/2.1.1.1.sh new file mode 100644 index 0000000..bee9019 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/2.1.1.1.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +{ + output="" l_tsd="" l_sdtd="" chrony="" l_ntp="" + dpkg-query -W chrony >/dev/null 2>&1 && l_chrony="y" + dpkg-query -W ntp >/dev/null 2>&1 && l_ntp="y" || l_ntp="" + systemctl list-units --all --type=service | grep -q 'systemd-timesyncd.service' && systemctl is-enabled systemd-timesyncd.service | grep -q 'enabled' && l_sdtd="y" + # ! systemctl is-enabled systemd-timesyncd.service | grep -q 'enabled' && l_nsdtd="y" || l_nsdtd="" + if [[ "$l_chrony" = "y" && "$l_ntp" != "y" && "$l_sdtd" != "y" ]]; then + l_tsd="chrony" + output="$output\n- chrony is in use on the system" + elif [[ "$l_chrony" != "y" && "$l_ntp" = "y" && "$l_sdtd" != "y" ]]; then + l_tsd="ntp" + output="$output\n- ntp is in use on the system" + elif [[ "$l_chrony" != "y" && "$l_ntp" != "y" ]]; then + if systemctl list-units --all --type=service | grep -q 'systemd-timesyncd.service' && systemctl is-enabled systemd-timesyncd.service | grep -Eq '(enabled|disabled|masked)'; then + l_tsd="sdtd" + output="$output\n- systemd-timesyncd is in use on the system" + fi + else + [[ "$l_chrony" = "y" && "$l_ntp" = "y" ]] && output="$output\n- both chrony and ntp are in use on the system" + [[ "$l_chrony" = "y" && "$l_sdtd" = "y" ]] && output="$output\n- both chrony and systemd-timesyncd are in use on the system" + [[ "$l_ntp" = "y" && "$l_sdtd" = "y" ]] && output="$output\n- both ntp and systemd-timesyncd are in use on the system" + fi + if [ -n "$l_tsd" ]; then + echo -e "\n- PASS:\n$output\n" + else + echo -e "\n- FAIL:\n$output\n" + fi +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/2.3.3.2.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/2.3.3.2.sh new file mode 100644 index 0000000..1175611 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/2.3.3.2.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +if ! command -v chronyd &>/dev/null; then + # chronyd is not installed + exit 0 +fi + +if ps -ef | grep -v grep | grep -q "chronyd"; then + if ps -ef | grep -v grep | grep "chronyd" | awk '{print $1}' | grep -q "^_chrony$"; then + exit 0 + else + exit 1 + fi +else + exit 0 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.1.1.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.1.1.sh new file mode 100644 index 0000000..9470c77 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.1.1.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +{ + output="" + grubfile=$(find /boot -type f \( -name 'grubenv' -o -name 'grub.conf' -o -name 'grub.cfg' \) -exec grep -Pl -- '^\h*(kernelopts=|linux|kernel)' {} \;) + searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf" + + if [ -s "$grubfile" ]; then + ! grep -P -- "^\h*(kernelopts=|linux|kernel)" "$grubfile" | grep -vq -- ipv6.disable=1 && output="IPv6 Disabled in \"$grubfile\"" + fi + + if + grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\h*(#.*)?$" $searchloc && \ + grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\h*(#.*)?$" $searchloc && \ + sysctl net.ipv6.conf.all.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\h*(#.*)?$" && \ + sysctl net.ipv6.conf.default.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\h*(#.*)?$" + then + [ -n "$output" ] && output="$output, and in sysctl config" || output="ipv6 disabled in sysctl config" + fi + + [ -n "$output" ] && echo -e "\n$output\n" || echo -e "\nIPv6 is enabled on the system\n" +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.1.6.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.1.6.sh new file mode 100644 index 0000000..082385c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.1.6.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +which ufw &>/dev/null || echo "no ufw" && exit 0 + +ufw_out="$(ufw status verbose)" +ss -tuln | awk '($5!~/%lo:/ && $5!~/127.0.0.1:/ && $5!~/::1/) {split($5, a, ":"); print a[2]}' | sort | uniq | while read -r lpn; do + ! grep -Pq "^\h*$lpn\b" <<<"$ufw_out" && echo "- Port: \"$lpn\" is missing a firewall rule" +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.2.10_1.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.2.10_1.sh new file mode 100644 index 0000000..33feb3a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.2.10_1.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +[ -n "$(grep -E '^\s*include' /etc/nftables.conf)" ] && awk '/hook input/,/}/' $(awk '$1 ~ /^\s*include/ { gsub("\"","",$2);print $2 }' /etc/nftables.conf) \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.2.10_2.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.2.10_2.sh new file mode 100644 index 0000000..3ec71e2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.2.10_2.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +[ -n "$(grep -E '^\s*include' /etc/nftables.conf)" ] && awk '/hook forward/,/}/' $(awk '$1 ~ /^\s*include/ { gsub("\"","",$2);print $2 }' /etc/nftables.conf) \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.2.10_3.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.2.10_3.sh new file mode 100644 index 0000000..46f6d37 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/3.5.2.10_3.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +[ -n "$(grep -E '^\s*include' /etc/nftables.conf)" ] && awk '/hook output/,/}/' $(awk '$1 ~ /^\s*include/ { gsub("\"","",$2);print $2 }' /etc/nftables.conf) \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/4.1.3.11_1.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/4.1.3.11_1.sh new file mode 100644 index 0000000..5275e7c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/4.1.3.11_1.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +{ + awk '/^ *-w/ \ +&&(/\/var\/run\/utmp/ \ + ||/\/var\/log\/wtmp/ \ + ||/\/var\/log\/btmp/) \ +&&/ +-p *wa/ \ +&&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/4.1.3.11_2.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/4.1.3.11_2.sh new file mode 100644 index 0000000..57f840a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/4.1.3.11_2.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +{ + auditctl -l | awk '/^ *-w/ \ +&&(/\/var\/run\/utmp/ \ + ||/\/var\/log\/wtmp/ \ + ||/\/var\/log\/btmp/) \ +&&/ +-p *wa/ \ +&&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/4.2.3.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/4.2.3.sh new file mode 100644 index 0000000..e76eaa7 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/4.2.3.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +checkForRules() { + # check if a Block states at least 1 reference (ufw blocks) + # and has more 2 lines (Input, Output, Forward blocks) + $1 -L | awk -v RS="\n\n" '$0 !~ /\(0 references\)/ && $0 ~ /.+\n.+\n.+/ {print $0}' +} + +[[ -n "$(checkForRules ip6tables)" || -n "$(checkForRules iptables)" ]] && exit 1 + +exit 0 \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.10.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.10.sh new file mode 100644 index 0000000..40eb8e2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.10.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +parameter_sshd_t=hostbasedauthentication +parameter_sshd_config=HostbasedAuthentication +desired_value=no + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq "^$parameter_sshd_config" /etc/ssh/sshd_config; then + actual_value=$(grep "^$parameter_sshd_config" /etc/ssh/sshd_config | awk '{print $2}') + else + exit 1 + + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.11.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.11.sh new file mode 100644 index 0000000..44c53ba --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.11.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +parameter_sshd_t=ignorerhosts +parameter_sshd_config=IgnoreRhosts +desired_value=yes + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config; then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + else + echo "$parameter_sshd_config not set in sshd_config, using default" + actual_value=no + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.12.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.12.sh new file mode 100644 index 0000000..002502f --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.12.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +output=$(sshd -T -C user=root -C host="$(hostname)" -C addr="$(hostname -I | cut -d ' ' -f1)" | grep -Ei "kexalgorithms\s+([^#\n\r]+,)?(diffie-hellman-group1-sha1|diffie-hellman-group14-sha1|diffie-hellman-group-exchange-sha1)\b") + +if [[ -n "$output" ]]; then + exit 1 +else + exit 0 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.13.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.13.sh new file mode 100644 index 0000000..55f58f2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.13.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +#test +parameter_sshd_t=logingracetime +parameter_sshd_config=LoginGraceTime +desired_value=60 + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config; then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + else + echo "$parameter_sshd_config not set in sshd_config, using default" + actual_value=120 + fi +fi + +if [ "$actual_value" -le "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.14.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.14.sh new file mode 100644 index 0000000..90d49f0 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.14.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +parameter_sshd_t=loglevel +parameter_sshd_config=LogLevel +desired_value=INFO +desired_value1=VERBOSE + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq "^$parameter_sshd_config" /etc/ssh/sshd_config; then + actual_value=$(grep "^$parameter_sshd_config" /etc/ssh/sshd_config | awk '{print $2}') + else + echo "$parameter_sshd_config not set in sshd_config, using default" + actual_value=INFO + fi +fi + +if [ "$actual_value" = "$desired_value" ] || [ "$actual_value" = "$desired_value1" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.15.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.15.sh new file mode 100644 index 0000000..e4b9ba7 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.15.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -Pi -- 'macs\h+([^#\n\r]+,)?(hmac-md5|hmac-md5-96|hmac-ripemd160|hmac-sha1-96|umac-64@openssh\.com|hmac-md5-etm@openssh\.com|hmac-md5-96-etm@openssh\.com|hmac-ripemd160-etm@openssh\.com|hmac-sha1-96-etm@openssh\.com|umac-64-etm@openssh\.com|umac-128-etm@openssh\.com)') + +if [ -z "$actual_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.17.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.17.sh new file mode 100644 index 0000000..9d1ac4d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.17.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +parameter_sshd_t=maxsessions +parameter_sshd_config=MaxSessions +FILE="/etc/ssh/sshd_config" +desired_value=10 + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + + if grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config; then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + else + exit 1 + fi +fi + +if [ "$actual_value" -le "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.18.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.18.sh new file mode 100644 index 0000000..e1d2b8d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.18.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +parameter_sshd_t=maxstartups +parameter_sshd_config=MaxStartups +desired_value="10:30:60" + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -Ei "^$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq "^$parameter_sshd_config" /etc/ssh/sshd_config; then + actual_value=$(grep -E "^$parameter_sshd_config" /etc/ssh/sshd_config | awk '{print $2}') + else + echo "$parameter_sshd_config not set in sshd_config, using default" + exit 1 + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.6.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.6.sh new file mode 100644 index 0000000..f392ffc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.6.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -Pi -- '^ciphers\h+\"?([^#\n\r]+,)?((3des|blowfish|cast128|aes(128|192|256))-cbc|arcfour(128|256)?|rijndael-cbc@lysator\.liu\.se|chacha20-poly1305@openssh\.com)') + +if [ -z "$actual_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.7.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.7.sh new file mode 100644 index 0000000..c1284aa --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.7.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +parameter_sshd_t=clientaliveinterval +parameter_sshd_config=ClientAliveInterval +desired_value=15 + +parameter_sshd_t1=clientalivecountmax +parameter_sshd_config1=ClientAliveCountMax +desired_value1=3 + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') +actual_value1=$(sshd -T | grep -i "$parameter_sshd_t1" | awk '{print $2}') + +if [ -z "$actual_value" ] && [ -z "$actual_value1" ]; then + if (grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config) && (grep -iq '^$parameter_sshd_config1' /etc/ssh/sshd_config); then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + actual_value1=$(grep -i '^$parameter_sshd_config1' /etc/ssh/sshd_config | awk '{print $2}') + + else + echo "$parameter_sshd_config not set in sshd_config, using default" + exit 1 + fi +fi + +if [ "$actual_value" -eq "$desired_value" ] && [ "$actual_value1" -eq "$desired_value1" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.8.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.8.sh new file mode 100644 index 0000000..89ecb6c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.8.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +parameter_sshd_t=disableforwarding +parameter_sshd_config=DisableForwarding +desired_value=yes + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config; then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + else + exit 1 + + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.9.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.9.sh new file mode 100644 index 0000000..49ee504 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.1.9.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +parameter_sshd_t=gssapiauthentication +parameter_sshd_config=GSSAPIAuthentication +desired_value=no + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq "^$parameter_sshd_config" /etc/ssh/sshd_config; then + actual_value=$(grep "^$parameter_sshd_config" /etc/ssh/sshd_config | awk '{print $2}') + else + + exit 1 + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.2.4.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.2.4.sh new file mode 100644 index 0000000..6e9b2a7 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.2.4.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +sufile="/etc/sudoers" +includes=$(awk '/^[^#]*(@|#)include(dir)?/{ + if ($1 ~ /^(@|#)includedir/) + print $2"/*"; + else print $2}' $sufile) + +for file in $sufile $includes; do + # exclude hardening file + if [[ ! $file =~ /\*$ ]] && grep -q "^[^#]*NOPASSWD" $file && [[ $file != "/etc/sudoers.d/DSC" ]]; then + exit 1 + fi +done + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.2.5.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.2.5.sh new file mode 100644 index 0000000..c6c181c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.2.5.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +sufile="/etc/sudoers" +includes=$(awk '/^[^#]*(@|#)include(dir)?/{ + if ($1 ~ /^(@|#)includedir/) + print $2"/*"; + else print $2}' $sufile) + +for file in $sufile $includes; do + if [[ ! $file =~ /\*$ ]] && grep -q "^[^#]*!authenticate" $file; then + exit 1 + fi +done + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.2.7.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.2.7.sh new file mode 100644 index 0000000..282cb7a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.2.7.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +# multiple groups can be configured to switch to diffrent set of users +while IFS='=' read -r _ confGroup; do + # options not in specific Order -> cut of + group="$(echo $confGroup | awk '{print $1}')" + membercount=$(grep -Pi "^$group:" /etc/group | awk -F ':' '{print $NF}' | awk -F ',' '{print NF}') + # groups should have no members + [[ $membercount -gt 0 ]] && exit 1 +done < <(grep -Pi '^\h*auth\h+(?:required|requisite)\h+pam_wheel\.so\h+(?:[^#\n\r]+\h+)?((?!\2)(use_uid\b|group=\H+\b))\h+(?:[^#\n\r]+\h+)?((?!\1)(use_uid\b|group=\H+\b))(\h+.*)?$' /etc/pam.d/su) + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.1.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.1.sh new file mode 100644 index 0000000..843c699 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.1.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +pam_files=("/etc/pam.d/common-account" "/etc/pam.d/common-session" "/etc/pam.d/common-auth" "/etc/pam.d/common-password") +pam_module="pam_unix.so" +error_found=false + +for file in "${pam_files[@]}"; do + echo "Checking $file..." + if grep -q "$pam_module" "$file"; then + echo "OK: $pam_module is enabled in $file" + else + echo "Error: $pam_module is NOT enabled in $file" + error_found=true + fi +done + +if [ "$error_found" = true ]; then + echo "Test Failed: pam_unix.so is NOT enabled in all PAM configuration files." + exit 1 +else + echo "Test Passed: pam_unix.so is enabled in all PAM configuration files." + exit 0 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.2.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.2.sh new file mode 100644 index 0000000..abca33b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.2.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +pam_path="/usr/share/pam-configs" +pam_files=("faillock" "faillock_notify") + +expected_faillock=( + 'Name: Enable pam_faillock to deny access' + 'Default: yes' + 'Priority: 0' + 'Auth-Type: Primary' + 'Auth: [default=die] pam_faillock.so authfail' +) +expected_faillock_notify=( + 'Name: Notify of failed login attempts and reset count upon success' + 'Default: yes' + 'Priority: 1024' + 'Auth-Type: Primary' + 'Auth: requisite pam_faillock.so preauth' + 'Account-Type: Primary' + 'Account: required pam_faillock.so' +) +check_profile() { + local profile_path="$pam_path/$1" + local expected_content=("${!2}") + + if [[ ! -f "$profile_path" ]]; then + echo "ERROR: Profile $profile_path does not exist." + exit 1 + fi + echo "Checking profile: $profile_path" + # Read the actual content of the profile file + for line in "${expected_content[@]}"; do + if ! grep -Fxq "$line" "$profile_path"; then + echo "ERROR: Expected line not found in $profile_path: $line" + exit 1 + fi + done +} +check_profile "faillock" expected_faillock[@] +check_profile "faillock_notify" expected_faillock_notify[@] diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.3.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.3.sh new file mode 100644 index 0000000..82ab4ca --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.3.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +pam_path="/usr/share/pam-configs" +profile_name="pwquality" + +expected_content=( + 'Name: Pwquality password strength checking' + 'Default: yes' + 'Priority: 1024' + 'Conflicts: cracklib' + 'Password-Type: Primary' + 'Password:' 'requisite pam_pwquality.so retry=3' + 'Password-Initial:' + 'requisite' +) +# check if the pwquality exists +if [[ -f "$pam_path/$profile_name" ]]; then + echo "$profile_name profile found in $pam_path:" +else + echo "ERROR: $profile_name profile not found in $pam_path." + exit 1 +fi + +# check content of pwquality +for line in "${expected_pwquality[@]}"; do + if ! grep -Fxq "$line" "$pam_path/$profile_name"; then + echo "ERROR: Expected line not found in $profile_name: $line" + exit 1 + fi +done +echo "pwquality profile content in $pam_path/$profile_name is correct." +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.4.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.4.sh new file mode 100644 index 0000000..fe86ec2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.2.4.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +pam_path="/usr/share/pam-configs" +profile_name="pwhistory" + +expected_content=( + 'Name: pwhistory password history checking' + 'Default: yes' + 'Priority: 1024' + 'Password-Type: Primary' 'Password:' + 'requisite pam_pwhistory.so remember=24 enforce_for_root try_first_pass use_authtok' +) + +# check content of pwhistory +if [[ -f "$pam_path/$profile_name" ]]; then + echo "$profile_name profile found in $pam_path:" +else + echo "ERROR: $profile_name profile not found in $pam_path." + exit 1 +fi + +# check content of pwhistory +for line in "${expected_pwquality[@]}"; do + if ! grep -Fxq "$line" "$pam_path/$profile_name"; then + echo "ERROR: Expected line not found in $profile_name: $line" + exit 1 + fi +done +echo "$profile_name profile content in $pam_path/$profile_name is correct." +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.2.7.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.2.7.sh new file mode 100644 index 0000000..fb0b279 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.2.7.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# Parameter to search for +parameter_config="enforcing" +unwanted_value=0 +file="/etc/security/pwquality.conf" + +# Search for the line containing the parameter with '=' and the unwanted value, even if commented +line=$(grep -E "^\s*$parameter_config\s*=\s*$unwanted_value\s*$" "$file") + +# Check if the unwanted line exists +if [ -n "$line" ]; then + echo "Error: The line '$parameter_config=$unwanted_value' exists in $file (even if commented)." + exit 1 +else + echo "No unwanted or commented line '$parameter_config=$unwanted_value' found in $file." + exit 0 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.2.8.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.2.8.sh new file mode 100644 index 0000000..ed6605d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.2.8.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# File configuration +FILE="/etc/security/pwquality.conf" +# what we look for +PATTERN="enforce_for_root" + +# Check if the file exists +if [ ! -f "$FILE" ]; then + echo "File $FILE wa not found." + exit 1 +fi + +# Search for the pattern, regardless of its case, even if it is commented out +grep -Ei "^[[:space:]]*#?[[:space:]]*$PATTERN" "$FILE" >/dev/null +FOUND=$? + +# if the pattern is found +if [ $FOUND -eq 0 ]; then + # check if it is commented + grep -Ei "^[[:space:]]*#[[:space:]]*$PATTERN" "$FILE" >/dev/null + COMMENTED=$? + + if [ $COMMENTED -eq 0 ]; then + exit 1 + fi + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.3.1.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.3.1.sh new file mode 100644 index 0000000..4405ee6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.3.1.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +files_to_check=$(awk '/Password-Type:/{ f = 1;next } /-Type:/{ f = 0 } f {if (/pam_pwhistory\.so/) print FILENAME}' /usr/share/pam-configs/*) +if [[ -z $files_to_check ]]; then + echo "file was not found" +else + for file in "$files_to_check"; do + if grep -Eq "pam_pwhistory\.so.*remember=" "$file"; then + current_value=$(grep -Eo "remember=[0-9]+" "$file" | grep -Eo "[0-9]+") + if [ "$current_value" -lt 24 ]; then + exit 1 + fi + else + exit 1 + fi + done + exit 0 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.3.2.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.3.2.sh new file mode 100644 index 0000000..0812856 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.3.2.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +files_to_check=$(awk '/Password-Type:/{ f = 1;next } /-Type:/{ f = 0 } f {if (/pam_pwhistory\.so/) print FILENAME}' /usr/share/pam-configs/*) +if [[ -z $files_to_check ]]; then + echo "file was not found" +else + for file in "$files_to_check"; do + if grep -Eq "pam_pwhistory\.so.*enforce_for_root" "$file"; then + exit 0 + else + exit 1 + fi + done + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.4.2.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.4.2.sh new file mode 100644 index 0000000..eed187c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.4.2.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +files_to_check=$(grep -El 'pam_unix\.so.*remember=' /usr/share/pam-configs/*) +if [[ -z "$files_to_check" ]]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.4.3.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.4.3.sh new file mode 100644 index 0000000..990d02d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.3.3.4.3.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +files_to_check=$(grep -Elz "Password-Type:.*\n.*pam_unix\.so" /usr/share/pam-configs/*) +if [ -z "$files_to_check" ]; then + echo "No relevant files found." + exit 0 +fi + +for file in $files_to_check; do + if ! grep -Eq "pam_unix\.so.*(yescrypt|sha512)" "$file"; then + exit 1 + fi +done +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.4.2.4.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.4.2.4.sh new file mode 100644 index 0000000..aab585f --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.4.2.4.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +root_password=$(getent shadow root | cut -d: -f2) + +if [[ "$root_password" == "*" || "$root_password" == "!" || -z "$root_password" ]]; then + exit 1 +fi + +exit 0 + diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.5.1.5.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.5.1.5.sh new file mode 100644 index 0000000..45b638f --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/5.5.1.5.sh @@ -0,0 +1,9 @@ +#!/bin/bash +{ + awk -F: '/^[^:]+:[^!*]/{print $1}' /etc/shadow | while read -r usr; do + change=$(date -d "$(chage --list $usr | grep '^Last password change' | cut -d: -f2 | grep -v 'never$')" +%s) + if [[ "$change" -gt "$(date +%s)" ]]; then + echo "User: \"$usr\" last password change was \"$(chage --list $usr | grep '^Last password change' | cut -d: -f2)\"" + fi + done +} diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.1.4.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.1.4.sh new file mode 100644 index 0000000..375bb76 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.1.4.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +regex_pattern="^\s*ForwardToSyslog\s*=\s*no" +config_files=("/etc/systemd/journald.conf" "/etc/systemd/journald.conf.d/*") + +for config_file in "${config_files[@]}"; do + for file in $config_file; do + if [[ -f "$file" ]]; then + if grep -qE "$regex_pattern" "$file"; then + exit 0 + fi + fi + done +done + +exit 1 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.1.5.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.1.5.sh new file mode 100644 index 0000000..d2f60bc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.1.5.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +regex_pattern="^\s*Storage\s*=\s*persistent" +config_files=("/etc/systemd/journald.conf" "/etc/systemd/journald.conf.d/*") + +for config_file in "${config_files[@]}"; do + for file in $config_file; do + if [[ -f "$file" ]]; then + if grep -qE "$regex_pattern" "$file"; then + exit 0 + fi + fi + done +done + +exit 1 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.1.6.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.1.6.sh new file mode 100644 index 0000000..ac47dad --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.1.6.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +regex_pattern="^\s*Compress\s*=\s*yes" +config_files=("/etc/systemd/journald.conf" "/etc/systemd/journald.conf.d/*") + +for config_file in "${config_files[@]}"; do + for file in $config_file; do + if [[ -f "$file" ]]; then + if grep -qE "$regex_pattern" "$file"; then + exit 0 + fi + fi + done +done + +exit 1 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.2.4.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.2.4.sh new file mode 100644 index 0000000..527ebb6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.1.2.4.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +socket_installed=$(systemctl list-unit-files | grep -q 'systemd-journal-remote.socket' && echo true || echo false) +service_installed=$(systemctl list-unit-files | grep -q 'systemd-journal-remote.service' && echo true || echo false) + +if [[ "$socket_installed" == "false" && "$service_installed" == "false" ]]; then + exit 0 # True if neither is installed +elif [[ "$socket_installed" == "true" && "$(systemctl is-active systemd-journal-remote.socket)" =~ ^(inactive|failed)$ ]] && + [[ "$service_installed" == "true" && "$(systemctl is-active systemd-journal-remote.service)" =~ ^(inactive|failed)$ ]]; then + exit 0 # True if both are not active (including failed) +else + exit 1 # False otherwise +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.3.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.3.sh new file mode 100644 index 0000000..8478396 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.3.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +for i in $(cut -s -d: -f4 /etc/passwd | sort -u); do + grep -q -P "^.*?:[^:]*:$i:" /etc/group || exit 1 +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.5.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.5.sh new file mode 100644 index 0000000..7d12fdf --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.5.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +cut -f3 -d":" /etc/passwd | sort -n | uniq -c | while read x; do + [ -z "$x" ] && break + set - $x + if [ $1 -gt 1 ]; then + users=$(awk -F: '($3 == n) { print $1 }' n=$2 /etc/passwd | xargs) + echo "Duplicate UID ($2): $users" + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.6.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.6.sh new file mode 100644 index 0000000..f7d6871 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.6.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cut -d: -f3 /etc/group | sort | uniq -d | while read x; do + echo "Duplicate GID ($x) in /etc/group" +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.7.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.7.sh new file mode 100644 index 0000000..f36bb79 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.7.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cut -d: -f1 /etc/passwd | sort | uniq -d | while read -r x; do + echo "Duplicate login name $x in /etc/passwd" +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.8.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.8.sh new file mode 100644 index 0000000..02ad855 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.8.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cut -d: -f1 /etc/group | sort | uniq -d | while read -r x; do + echo "Duplicate group name $x in /etc/group" +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.9.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.9.sh new file mode 100644 index 0000000..f5cc42e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.2.9.sh @@ -0,0 +1,9 @@ +#!/bin/bash +awk -F: '($1!~/(root|halt|sync|shutdown)/ && $7!~/^(\/usr)?\/sbin\/nologin(\/)?$/ && $7!~/(\/usr)?\/bin\/false(\/)?$/) { print $1 " " $6 }' /etc/passwd | while read -r user dir; do + if [ -d "$dir" ]; then + file="$dir/.forward" + if [ ! -h "$file" ] && [ -f "$file" ]; then + echo "User: \"$user\" file: \"$file\" exists" + fi + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.1.3.sh new file mode 100644 index 0000000..7b3479d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.1.3.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +GRUB_CFG="/etc/default/grub" + +if [[ ! -f "$GRUB_CFG" ]]; then + echo "Error: $GRUB_CFG does not exist." + exit 1 +fi +if grep -q "audit=1" "$GRUB_CFG"; then + echo "Found 'audit=1' in $GRUB_CFG." + exit 0 +else + echo "'audit=1' not found in $GRUB_CFG." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.1.4.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.1.4.sh new file mode 100644 index 0000000..158b8cc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.1.4.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +GRUB_CFG="/etc/default/grub" + +if [[ ! -f "$GRUB_CFG" ]]; then + echo "Error: $GRUB_CFG does not exist." + exit 1 +fi +if grep -q "audit_backlog_limit" "$GRUB_CFG"; then + echo "Found 'audit_backlog_limit=1' in $GRUB_CFG." + exit 0 +else + echo "'audit_backlog_limit=1' not found in $GRUB_CFG." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.1.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.1.sh new file mode 100644 index 0000000..a8027ab --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.1.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +l_perm_mask="0137" +if [ -e "/etc/audit/auditd.conf" ]; then + # Extract the log directory from the configuration file + l_audit_log_directory="$(dirname "$(awk -F= '/^\s*log_file\s*/{print $2}' /etc/audit/auditd.conf | xargs)")" + + if [ -d "$l_audit_log_directory" ]; then + l_maxperm="$(printf '%o' $((0777 & ~$l_perm_mask)))" + + # Find files matching the permission mask and process them line by line + while IFS= read -r l_file; do + # Ensure the file exists and get its mode + if [ -e "$l_file" ]; then + l_file_mode="$(stat -Lc '%#a' "$l_file")" + exit 1 + fi + done < <(find "$l_audit_log_directory" -maxdepth 1 -type f -perm /"$l_perm_mask") + + # Check if any files were processed + if [ $? -eq 0 ]; then + exit 0 + fi + else + exit 0 + fi +else + exit 0 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.2.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.2.sh new file mode 100644 index 0000000..9bf99dc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.2.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +l_output="" l_output2="" +if [ -e "/etc/audit/auditd.conf" ]; then + l_audit_log_directory="$(dirname "$(awk -F= '/^\s*log_file\s*/{print $2}' /etc/audit/auditd.conf | xargs)")" + if [ -d "$l_audit_log_directory" ]; then + while IFS= read -r l_file; do + l_output2="$l_output2\n - File: \"$l_file\" is owned by user: \"$(stat -Lc '%U' "$l_file")\"\n (should be owned by user: \"root\")\n" + done < <(find "$l_audit_log_directory" -maxdepth 1 -type f ! -user root) + else + l_output2="$l_output2\n - Log file directory not set in \"/etc/audit/auditd.conf\" please set log file directory" + fi +else + l_output2="$l_output2\n - File: \"/etc/audit/auditd.conf\" not found.\n - ** Verify auditd is installed **" +fi +if [ -z "$l_output2" ]; then + l_output="$l_output\n - All files in \"$l_audit_log_directory\" are owned by user: \"root\"\n" + echo -e "\n- Audit Result:\n ** PASS **\n - * Correctly configured * :$l_output" + exit 0 +else + echo -e "\n- Audit Result:\n ** FAIL **\n - * Reasons for auditgfailure * :$l_output2\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.3.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.3.sh new file mode 100644 index 0000000..b5e03bd --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.3.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +audit_conf="/etc/audit/auditd.conf" +perm_mask="0177" +if [ ! -f "$audit_conf" ]; then + exit 1 +fi +audit_log_dir=$(grep -E '^\s*log_file\s*=' "$audit_conf" | cut -d= -f2 | xargs dirname 2>/dev/null) +if [ -z "$audit_log_dir" ]; then + exit 1 +fi +audit_log_group=$(grep -E '^\s*log_group\s*=' "$audit_conf" | cut -d= -f2 | xargs) +if [ -z "$audit_log_group" ]; then + exit 1 +fi +if [ ! -d "$audit_log_dir" ]; then + exit 1 +fi +for file in "$audit_log_dir"/*; do + if [ -f "$file" ]; then + group=$(ls -l "$file" | awk '{print $4}') + if [[ "$group" != "root" && "$group" != "adm" ]]; then + exit 1 + fi + fi +done +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.4.sh b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.4.sh new file mode 100644 index 0000000..dc826da --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/Ubuntu22.04_Debian12/6.3.4.4.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +perm_mask="0027" +if [ -e "/etc/audit/auditd.conf" ]; then + log_dir="$(dirname "$(awk -F= '/^\s*log_file\s*/{print $2}' /etc/audit/auditd.conf | xargs)")" + if [ -d "$log_dir" ]; then + maxperm="$(printf '%o' $((0777 & ~$perm_mask)))" + log_dir_mode="$(stat -Lc '%#a' "$log_dir")" + if [ $(($log_dir_mode & $perm_mask)) -gt 0 ]; then + exit 1 + fi + else + exit 1 + fi +else + exit 1 +fi +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.1.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.1.sh new file mode 100644 index 0000000..efdde75 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.1.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +l_output="" l_output2="" l_output3="" l_dl="" # Unset output variables +l_mname="cramfs" # set module name +l_mtype="fs" # set module type +l_searchloc="/lib/modprobe.d/*.conf /usr/local/lib/modprobe.d/*.conf /run/modprobe.d/*.conf /etc/modprobe.d/*.conf" +l_mpath="/lib/modules/**/kernel/$l_mtype" +l_mpname="$(tr '-' '_' <<<"$l_mname")" +l_mndir="$(tr '-' '/' <<<"$l_mname")" +module_loadable_chk() { + # Check if the module is currently loadable + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi +} +module_loaded_chk() { + # Check if the module is currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi +} +module_deny_chk() { + # Check if the module is deny listed + l_dl="y" + if modprobe --showconfig | grep -Pq -- '^\h*blacklist\h+'"$l_mpname"'\b'; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pls -- "^\h*blacklist\h+$l_mname\b" $l_searchloc)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +# Check if the module exists on the system +for l_mdir in $l_mpath; do + if [ -d "$l_mdir/$l_mndir" ] && [ -n "$(ls -A $l_mdir/$l_mndir)" ]; then + l_output3="$l_output3\n - \"$l_mdir\"" + [ "$l_dl" != "y" ] && module_deny_chk + if [ "$l_mdir" = "/lib/modules/$(uname -r)/kernel/$l_mtype" ]; then + module_loadable_chk + module_loaded_chk + fi + else + l_output="$l_output\n - module: \"$l_mname\" doesn't exist in \"$l_mdir\"" + fi +done +# Report results. If no failures output in l_output2, we pass +[ -n "$l_output3" ] && echo -e "\n\n -- INFO --\n - module: \"$l_mname\" exists in:$l_output3" +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + exit 0 +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.2.sh new file mode 100644 index 0000000..eb66ae8 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.2.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +l_output="" l_output2="" l_output3="" l_dl="" # Unset output variables +l_mname="freevxfs" # set module name +l_mtype="fs" # set module type +l_searchloc="/lib/modprobe.d/*.conf /usr/local/lib/modprobe.d/*.conf /run/modprobe.d/*.conf /etc/modprobe.d/*.conf" +#replaced in original script to avoid globstar operator +l_mpath=$(find /lib/modules/ -type d -name $l_mtype) +l_mpname="$(tr '-' '_' <<<"$l_mname")" +l_mndir="$(tr '-' '/' <<<"$l_mname")" +module_loadable_chk() { + # Check if the module is currently loadable + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi +} +module_loaded_chk() { + # Check if the module is currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi +} +module_deny_chk() { + # Check if the module is deny listed + l_dl="y" + if modprobe --showconfig | grep -Pq -- '^\h*blacklist\h+'"$l_mpname"'\b'; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pls -- "^\h*blacklist\h+$l_mname\b" $l_searchloc)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +# Check if the module exists on the system +for l_mdir in $l_mpath; do + if [ -d "$l_mdir/$l_mndir" ] && [ -n "$(ls -A $l_mdir/$l_mndir)" ]; then + l_output3="$l_output3\n - \"$l_mdir\"" + [ "$l_dl" != "y" ] && module_deny_chk + if [ "$l_mdir" = "/lib/modules/$(uname -r)/kernel/$l_mtype" ]; then + module_loadable_chk + module_loaded_chk + fi + else + l_output="$l_output\n - module: \"$l_mname\" doesn't exist in \"$l_mdir\"" + fi +done +# Report results. If no failures output in l_output2, we pass +[ -n "$l_output3" ] && echo -e "\n\n -- INFO --\n - module: \"$l_mname\" exists in:$l_output3" +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + exit 0 +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.3.sh new file mode 100644 index 0000000..852aa83 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.3.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +l_output="" l_output2="" l_output3="" l_dl="" # Unset output variables +l_mname="hfs" # set module name +l_mtype="fs" # set module type +l_searchloc="/lib/modprobe.d/*.conf /usr/local/lib/modprobe.d/*.conf /run/modprobe.d/*.conf /etc/modprobe.d/*.conf" +l_mpath="/lib/modules/**/kernel/$l_mtype" +l_mpname="$(tr '-' '_' <<<"$l_mname")" +l_mndir="$(tr '-' '/' <<<"$l_mname")" +module_loadable_chk() { + # Check if the module is currently loadable + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi +} +module_loaded_chk() { + # Check if the module is currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi +} +module_deny_chk() { + # Check if the module is deny listed + l_dl="y" + if modprobe --showconfig | grep -Pq -- '^\h*blacklist\h+'"$l_mpname"'\b'; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pls -- "^\h*blacklist\h+$l_mname\b" $l_searchloc)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +# Check if the module exists on the system +for l_mdir in $l_mpath; do + if [ -d "$l_mdir/$l_mndir" ] && [ -n "$(ls -A $l_mdir/$l_mndir)" ]; then + l_output3="$l_output3\n - \"$l_mdir\"" + [ "$l_dl" != "y" ] && module_deny_chk + if [ "$l_mdir" = "/lib/modules/$(uname -r)/kernel/$l_mtype" ]; then + module_loadable_chk + module_loaded_chk + fi + else + l_output="$l_output\n - module: \"$l_mname\" doesn't exist in \"$l_mdir\"" + fi +done +# Report results. If no failures output in l_output2, we pass +[ -n "$l_output3" ] && echo -e "\n\n -- INFO --\n - module: \"$l_mname\" exists in:$l_output3" +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + exit 0 +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.4.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.4.sh new file mode 100644 index 0000000..1753ecf --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.4.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +l_output="" l_output2="" l_output3="" l_dl="" # Unset output variables +l_mname="hfsplus" # set module name +l_mtype="fs" # set module type +l_searchloc="/lib/modprobe.d/*.conf /usr/local/lib/modprobe.d/*.conf /run/modprobe.d/*.conf /etc/modprobe.d/*.conf" +l_mpath="/lib/modules/**/kernel/$l_mtype" +l_mpname="$(tr '-' '_' <<<"$l_mname")" +l_mndir="$(tr '-' '/' <<<"$l_mname")" +module_loadable_chk() { + # Check if the module is currently loadable + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi +} +module_loaded_chk() { + # Check if the module is currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi +} +module_deny_chk() { + # Check if the module is deny listed + l_dl="y" + if modprobe --showconfig | grep -Pq -- '^\h*blacklist\h+'"$l_mpname"'\b'; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pls -- "^\h*blacklist\h+$l_mname\b" $l_searchloc)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +# Check if the module exists on the system +for l_mdir in $l_mpath; do + if [ -d "$l_mdir/$l_mndir" ] && [ -n "$(ls -A $l_mdir/$l_mndir)" ]; then + l_output3="$l_output3\n - \"$l_mdir\"" + [ "$l_dl" != "y" ] && module_deny_chk + if [ "$l_mdir" = "/lib/modules/$(uname -r)/kernel/$l_mtype" ]; then + module_loadable_chk + module_loaded_chk + fi + else + l_output="$l_output\n - module: \"$l_mname\" doesn't exist in \"$l_mdir\"" + fi +done +# Report results. If no failures output in l_output2, we pass +[ -n "$l_output3" ] && echo -e "\n\n -- INFO --\n - module: \"$l_mname\" exists in:$l_output3" +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + exit 0 +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.5.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.5.sh new file mode 100644 index 0000000..1dca087 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.5.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +l_output="" l_output2="" l_output3="" l_dl="" # Unset output variables +l_mname="jffs2" # set module name +l_mtype="fs" # set module type +l_searchloc="/lib/modprobe.d/*.conf /usr/local/lib/modprobe.d/*.conf /run/modprobe.d/*.conf /etc/modprobe.d/*.conf" +l_mpath="/lib/modules/**/kernel/$l_mtype" +l_mpname="$(tr '-' '_' <<<"$l_mname")" +l_mndir="$(tr '-' '/' <<<"$l_mname")" +module_loadable_chk() { + # Check if the module is currently loadable + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi +} +module_loaded_chk() { + # Check if the module is currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi +} +module_deny_chk() { + # Check if the module is deny listed + l_dl="y" + if modprobe --showconfig | grep -Pq -- '^\h*blacklist\h+'"$l_mpname"'\b'; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pls -- "^\h*blacklist\h+$l_mname\b" $l_searchloc)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +# Check if the module exists on the system +for l_mdir in $l_mpath; do + if [ -d "$l_mdir/$l_mndir" ] && [ -n "$(ls -A $l_mdir/$l_mndir)" ]; then + l_output3="$l_output3\n - \"$l_mdir\"" + [ "$l_dl" != "y" ] && module_deny_chk + if [ "$l_mdir" = "/lib/modules/$(uname -r)/kernel/$l_mtype" ]; then + module_loadable_chk + module_loaded_chk + fi + else + l_output="$l_output\n - module: \"$l_mname\" doesn't exist in \"$l_mdir\"" + fi +done +# Report results. If no failures output in l_output2, we pass +[ -n "$l_output3" ] && echo -e "\n\n -- INFO --\n - module: \"$l_mname\" exists in:$l_output3" +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + exit 0 +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.6.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.6.sh new file mode 100644 index 0000000..51bd145 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.6.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +l_output="" l_output2="" l_output3="" l_dl="" # Unset output variables +l_mname="squashfs" # set module name +l_mtype="fs" # set module type +l_searchloc="/lib/modprobe.d/*.conf /usr/local/lib/modprobe.d/*.conf /run/modprobe.d/*.conf /etc/modprobe.d/*.conf" +#replaced in original script to avoid globstar operator +l_mpath=$(find /lib/modules/ -type d -name $l_mtype) +l_mpname="$(tr '-' '_' <<<"$l_mname")" +l_mndir="$(tr '-' '/' <<<"$l_mname")" +module_loadable_chk() { + # Check if the module is currently loadable + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$( + grep -P -- + "(^\h*install|\b$l_mname)\b" <<<"$l_loadable" + )" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi +} +module_loaded_chk() { + # Check if the module is currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi +} +module_deny_chk() { + # Check if the module is deny listed + l_dl="y" + if modprobe --showconfig | grep -Pq -- '^\h*blacklist\h+'"$l_mpname"'\b'; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pls -- "^\h*blacklist\h+$l_mname\b" $l_searchloc)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +# Check if the module exists on the system +for l_mdir in $l_mpath; do + if [ -d "$l_mdir/$l_mndir" ] && [ -n "$(ls -A $l_mdir/$l_mndir)" ]; then + l_output3="$l_output3\n - \"$l_mdir\"" + [ "$l_dl" != "y" ] && module_deny_chk + if [ "$l_mdir" = "/lib/modules/$(uname -r)/kernel/$l_mtype" ]; then + module_loadable_chk + module_loaded_chk + fi + else + l_output="$l_output\n - module: \"$l_mname\" doesn't exist in \"$l_mdir\"" + fi +done +# Report results. If no failures output in l_output2, we pass +[ -n "$l_output3" ] && echo -e "\n\n -- INFO --\n - module: \"$l_mname\" exists in:$l_output3" +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + exit 0 +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.7.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.7.sh new file mode 100644 index 0000000..6bd152c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.7.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +l_output="" l_output2="" l_output3="" l_dl="" # Unset output variables +l_mname="udf" # set module name +l_mtype="fs" # set module type +l_searchloc="/lib/modprobe.d/*.conf /usr/local/lib/modprobe.d/*.conf /run/modprobe.d/*.conf /etc/modprobe.d/*.conf" +#replaced in original script to avoid globstar operator +l_mpath=$(find /lib/modules/ -type d -name $l_mtype) +l_mpname="$(tr '-' '_' <<<"$l_mname")" +l_mndir="$(tr '-' '/' <<<"$l_mname")" +module_loadable_chk() { + # Check if the module is currently loadable + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi +} +module_loaded_chk() { + # Check if the module is currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi +} +module_deny_chk() { + # Check if the module is deny listed + l_dl="y" + if modprobe --showconfig | grep -Pq -- '^\h*blacklist\h+'"$l_mpname"'\b'; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pls -- "^\h*blacklist\h+$l_mname\b" $l_searchloc)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +# Check if the module exists on the system +for l_mdir in $l_mpath; do + if [ -d "$l_mdir/$l_mndir" ] && [ -n "$(ls -A $l_mdir/$l_mndir)" ]; then + l_output3="$l_output3\n - \"$l_mdir\"" + [ "$l_dl" != "y" ] && module_deny_chk + if [ "$l_mdir" = "/lib/modules/$(uname -r)/kernel/$l_mtype" ]; then + module_loadable_chk + module_loaded_chk + fi + else + l_output="$l_output\n - module: \"$l_mname\" doesn't exist in \"$l_mdir\"" + fi +done +# Report results. If no failures output in l_output2, we pass +[ -n "$l_output3" ] && echo -e "\n\n -- INFO --\n - module: \"$l_mname\" exists in:$l_output3" +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.8.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.8.sh new file mode 100644 index 0000000..bb1ec34 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.1.8.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +l_output="" l_output2="" l_output3="" l_dl="" # Unset output variables +l_mname="usb-storage" # set module name +l_mtype="drivers" # set module type +l_searchloc="/lib/modprobe.d/*.conf /usr/local/lib/modprobe.d/*.conf /run/modprobe.d/*.conf /etc/modprobe.d/*.conf" +#replaced in original script to avoid globstar operator +l_mpath=$(find /lib/modules/ -type d -name $l_mtype) +l_mpname="$(tr '-' '_' <<<"$l_mname")" +l_mndir="$(tr '-' '/' <<<"$l_mname")" +module_loadable_chk() { + # Check if the module is currently loadable + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi +} +module_loaded_chk() { + # Check if the module is currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi +} +module_deny_chk() { + # Check if the module is deny listed + l_dl="y" + if modprobe --showconfig | grep -Pq -- '^\h*blacklist\h+'"$l_mpname"'\b'; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pls -- "^\h*blacklist\h+$l_mname\b" $l_searchloc)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +# Check if the module exists on the system +for l_mdir in $l_mpath; do + if [ -d "$l_mdir/$l_mndir" ] && [ -n "$(ls -A $l_mdir/$l_mndir)" ]; then + l_output3="$l_output3\n - \"$l_mdir\"" + [ "$l_dl" != "y" ] && module_deny_chk + if [ "$l_mdir" = "/lib/modules/$(uname -r)/kernel/$l_mtype" ]; then + module_loadable_chk + module_loaded_chk + fi + else + l_output="$l_output\n - module: \"$l_mname\" doesn't exist in \"$l_mdir\"" + fi +done +# Report results. If no failures output in l_output2, we pass +[ -n "$l_output3" ] && echo -e "\n\n -- INFO --\n - module: \"$l_mname\" exists in:$l_output3" +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" + exit 0 +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.1.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.1.2.sh new file mode 100644 index 0000000..c087447 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.1.2.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +if grep -q -E '^[^#]*\s/tmp\s' /etc/fstab; then + if grep -E '^[^#]*\s/tmp\s' /etc/fstab | grep -vq 'nodev'; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.1.3.sh new file mode 100644 index 0000000..c13380b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.1.3.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +if grep -q -E '^[^#]*\s/tmp\s' /etc/fstab; then + # If such a line exists, check if it contains the nosuid flag + if grep -E '^[^#]*\s/tmp\s' /etc/fstab | grep -vq 'nosuid'; then + # If /var exists and does NOT contain nosuid, exit with 1 (error) + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.2.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.2.2.sh new file mode 100644 index 0000000..08bf662 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.2.2.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/dev/shm" +flag="nodev" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.2.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.2.3.sh new file mode 100644 index 0000000..9febe98 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.2.3.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/dev/shm" +flag="nosuid" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.2.4.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.2.4.sh new file mode 100644 index 0000000..b6ca433 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.2.4.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/dev/shm" +flag="noexec" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.3.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.3.2.sh new file mode 100644 index 0000000..6b94c6e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.3.2.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/home" +flag="nodev" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.3.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.3.3.sh new file mode 100644 index 0000000..5c1a16b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.3.3.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +if grep -q -E '^[^#]*\s/home\s' /etc/fstab; then + if grep -E '^[^#]*\s/home\s' /etc/fstab | grep -vq 'nosuid'; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.4.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.4.2.sh new file mode 100644 index 0000000..c385df1 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.4.2.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +if grep -q -E '^[^#]*\s/var\s' /etc/fstab; then + # If such a line exists, check if it contains the nodev flag + if grep -E '^[^#]*\s/var\s' /etc/fstab | grep -vq 'nodev'; then + # If /var exists and does NOT contain nodev, exit with 1 (error) + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.4.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.4.3.sh new file mode 100644 index 0000000..97dc6a0 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.4.3.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +if grep -q -E '^[^#]*\s/var\s' /etc/fstab; then + # If such a line exists, check if it contains the nosuid flag + if grep -E '^[^#]*\s/var\s' /etc/fstab | grep -vq 'nosuid'; then + # If /var exists and does NOT contain nosuid, exit with 1 (error) + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.5.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.5.2.sh new file mode 100644 index 0000000..ae55f46 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.5.2.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/var/tmp" +flag="nodev" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.5.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.5.3.sh new file mode 100644 index 0000000..8ffc050 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.5.3.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/var/tmp" +flag="nosuid" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.5.4.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.5.4.sh new file mode 100644 index 0000000..c35e9eb --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.5.4.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/var/tmp" +flag="noexec" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.6.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.6.2.sh new file mode 100644 index 0000000..e341c1d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.6.2.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/var/log" +flag="nodev" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.6.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.6.3.sh new file mode 100644 index 0000000..3880665 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.6.3.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/var/log" +flag="nosuid" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.6.4.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.6.4.sh new file mode 100644 index 0000000..547b916 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.6.4.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/var/log" +flag="noexec" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.7.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.7.2.sh new file mode 100644 index 0000000..85b3d8b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.7.2.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/var/log/audit" +flag="nodev" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.7.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.7.3.sh new file mode 100644 index 0000000..2e33863 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.7.3.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/var/log/audit" +flag="nosuid" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.7.4.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.7.4.sh new file mode 100644 index 0000000..9d49387 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.1.2.7.4.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +directory="/var/log/audit" +flag="noexec" +FSTAB_FILE="/etc/fstab" + +if [[ ! -f "$FSTAB_FILE" ]]; then + echo "Error: $FSTAB_FILE does not exist." + exit 0 +fi + +if grep -q -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE"; then + if grep -E "^[^#]*[[:space:]]+$directory[[:space:]]+" "$FSTAB_FILE" | grep -vq "$flag"; then + exit 1 + fi +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.4.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.4.2.sh new file mode 100644 index 0000000..611a780 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.4.2.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +# Define the paths to check for grub.cfg +UBUNTU_GRUB_PATH="/boot/grub/grub.cfg" +REDHAT_GRUB_PATH="/boot/grub2/grub.cfg" + +# Function to check permissions +check_permissions() { + local file_path="$1" + if [ -f "$file_path" ]; then + # Get the file's permissions in octal format + permissions=$(stat -c "%a" "$file_path") + if [ "$permissions" -eq 600 ]; then + echo "Permissions for $file_path are correct (600)." + exit 0 + else + echo "Permissions for $file_path are incorrect ($permissions)." + exit 1 + fi + fi +} + +# Check for Ubuntu path +check_permissions "$UBUNTU_GRUB_PATH" + +# Check for Red Hat path +check_permissions "$REDHAT_GRUB_PATH" + +# If neither file is found, exit with an error +echo "grub.cfg file not found in the expected locations." +exit 1 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.5.1.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.5.1.sh new file mode 100644 index 0000000..b4337a6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.5.1.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +kernel_parameter="kernel.randomize_va_space" +kernel_value="2" + +current_value=$(sysctl -n "$kernel_parameter" 2>/dev/null) + +if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $kernel_parameter does not exist or could not be retrieved." + exit 1 +fi + +if [ "$current_value" == "$kernel_value" ]; then + echo "Kernel parameter $kernel_parameter is set to $kernel_value" + exit 0 +else + echo "Kernel parameter $kernel_parameter is not set to $kernel_value (current value: $current_value)" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/1.5.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/1.5.2.sh new file mode 100644 index 0000000..804715e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/1.5.2.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +kernel_parameter="kernel.yama.ptrace_scope" +kernel_value="1" +current_value=$(sysctl -n "$kernel_parameter" 2>/dev/null) + +if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $kernel_parameter does not exist or could not be retrieved." + exit 1 +fi + +if [ "$current_value" == "$kernel_value" ]; then + echo "Kernel parameter $kernel_parameter is set to $kernel_value" + exit 0 +else + echo "Kernel parameter $kernel_parameter is not set to $kernel_value (current value: $current_value)" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/2.1.13.sh b/ATAPAuditor/Helpers/ShellScripts/common/2.1.13.sh new file mode 100644 index 0000000..49e1858 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/2.1.13.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +PATTERN='rsyncd?\.service|rsyncd\.socket' + +# DebUntu rsync.service +# rhel rsyncd.service und rsyncd.socket +services=$(systemctl list-unit-files | grep -oE $PATTERN) +for service in $services; +do + if systemctl is-enabled $service 1>/dev/null 2>/dev/null; then + exit 1 + fi +done + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/2.4.1.8.sh b/ATAPAuditor/Helpers/ShellScripts/common/2.4.1.8.sh new file mode 100644 index 0000000..4692a30 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/2.4.1.8.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +# Define the files to check +FILES=("/etc/cron.allow" "/etc/cron.deny") + +# Function to check a file +check_file() { + local file=$1 + + # Check if the file exists + if [ ! -e "$file" ]; then + echo "File $file does not exist. Ignoring." + return 0 + fi + + # Get the file permissions in numeric format + local permissions=$(stat -c "%a" "$file") + local owner=$(stat -c "%U" "$file") + local group=$(stat -c "%G" "$file") + + # Check if the file permissions are 0640 or more restrictive + if [ "$permissions" -gt 640 ]; then + echo "File $file permissions are not 0640 or more restrictive." + return 1 + fi + + # Check if the owner is root and group is root + if [ "$owner" != "root" ] || [ "$group" != "root" ]; then + echo "File $file owner or group is not root." + return 1 + fi + + return 0 +} + +# Check each file +for file in "${FILES[@]}"; do + if ! check_file "$file"; then + exit 1 + fi +done + +# If all checks pass, exit with status 0 +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/2.4.2.1.sh b/ATAPAuditor/Helpers/ShellScripts/common/2.4.2.1.sh new file mode 100644 index 0000000..6fa5d37 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/2.4.2.1.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# Define the files to check +FILES=("/etc/at.allow" "/etc/at.deny") + +check_file() { + local file=$1 + + # Check if the file exists + if [ ! -e "$file" ]; then + echo "File $file does not exist. Ignoring." + return 0 + fi + + # Get the file permissions in numeric format + local permissions=$(stat -c "%a" "$file") + local owner=$(stat -c "%U" "$file") + local group=$(stat -c "%G" "$file") + + # Check if the file permissions are 0640 or more restrictive + if [ "$permissions" -gt 640 ]; then + echo "File $file permissions are not 0640 or more restrictive." + return 1 + fi + + # Check if the owner is root and group is root + if [ "$owner" != "root" ] || [ "$group" != "root" ]; then + echo "File $file owner or group is not root." + return 1 + fi + + return 0 +} + +# Check each file +for file in "${FILES[@]}"; do + if ! check_file "$file"; then + exit 1 + fi +done + +# If all checks pass, exit with status 0 +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.1.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.1.2.sh new file mode 100644 index 0000000..a508fc2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.1.2.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +l_output="" l_output2="" +module_chk() { + # Check how module will be loaded + l_loadable="$(modprobe -n -v "$l_mname")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi + # Check is the module currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi + # Check if the module is deny listed + if modprobe --showconfig | grep -Pq -- "^\h*blacklist\h+$l_mname\b"; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +if [ -n "$(find /sys/class/net/*/ -type d -name wireless)" ]; then + l_dname=$(for driverdir in $(find /sys/class/net/*/ -type d -name wireless | xargs -0 dirname); do basename "$(readlink -f "$driverdir"/device/driver/module)"; done | sort -u) + for l_mname in $l_dname; do + module_chk + done +fi +# Report results. If no failures output in l_output2, we pass +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **" + if [ -z "$l_output" ]; then + echo -e "\n - System has no wireless NICs installed" + else + echo -e "\n$l_output\n" + fi +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.2.1.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.2.1.sh new file mode 100644 index 0000000..9d23af8 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.2.1.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +l_output="" l_output2="" l_output3="" l_dl="" # Unset output variables +l_mname="dccp" # set module name +l_mtype="net" # set module type +#replaced in original script to avoid wildcard +l_searchloc=$(find $(for dir in /lib/modprobe.d /usr/local/lib/modprobe.d /run/modprobe.d /etc/modprobe.d; do [[ -d "$dir" ]] && echo "$dir"; done) -type f -name "*.conf" 2>/dev/null) +#replaced in original script to avoid globstar operator +l_mpath=$(find /lib/modules/ -type d -name $l_mtype) +l_mpname="$(tr '-' '_' <<<"$l_mname")" +l_mndir="$(tr '-' '/' <<<"$l_mname")" +module_loadable_chk() { + # Check if the module is currently loadable + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi +} +module_loaded_chk() { + # Check if the module is currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi +} +module_deny_chk() { + # Check if the module is deny listed + l_dl="y" + if modprobe --showconfig | grep -Pq -- '^\h*blacklist\h+'"$l_mpname"'\b'; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pls -- "^\h*blacklist\h+$l_mname\b" $l_searchloc)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +# Check if the module exists on the system +for l_mdir in $l_mpath; do + if [ -d "$l_mdir/$l_mndir" ] && [ -n "$(ls -A $l_mdir/$l_mndir)" ]; then + l_output3="$l_output3\n - \"$l_mdir\"" + [ "$l_dl" != "y" ] && module_deny_chk + if [ "$l_mdir" = "/lib/modules/$(uname -r)/kernel/$l_mtype" ]; then + module_loadable_chk + module_loaded_chk + fi + else + l_output="$l_output\n - module: \"$l_mname\" doesn't exist in \"$l_mdir\"" + fi +done +# Report results. If no failures output in l_output2, we pass +[ -n "$l_output3" ] && echo -e "\n\n -- INFO --\n - module: \"$l_mname\" exists in:$l_output3" +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.2.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.2.2.sh new file mode 100644 index 0000000..de75e39 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.2.2.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +l_output="" l_output2="" l_output3="" l_dl="" # Unset output variables +l_mname="tipc" # set module name +l_mtype="net" # set module type +#replaced in original script to avoid wildcard +l_searchloc=$(find $(for dir in /lib/modprobe.d /usr/local/lib/modprobe.d /run/modprobe.d /etc/modprobe.d; do [[ -d "$dir" ]] && echo "$dir"; done) -type f -name "*.conf" 2>/dev/null) +#replaced in original script to avoid globstar operator +l_mpath=$(find /lib/modules/ -type d -name $l_mtype) +l_mpname="$(tr '-' '_' <<<"$l_mname")" +l_mndir="$(tr '-' '/' <<<"$l_mname")" +module_loadable_chk() { + # Check if the module is currently loadable + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi +} +module_loaded_chk() { + # Check if the module is currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi +} +module_deny_chk() { + # Check if the module is deny listed + l_dl="y" + if modprobe --showconfig | grep -Pq -- '^\h*blacklist\h+'"$l_mpname"'\b'; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pls -- "^\h*blacklist\h+$l_mname\b" $l_searchloc)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +# Check if the module exists on the system +for l_mdir in $l_mpath; do + if [ -d "$l_mdir/$l_mndir" ] && [ -n "$(ls -A $l_mdir/$l_mndir)" ]; then + l_output3="$l_output3\n - \"$l_mdir\"" + [ "$l_dl" != "y" ] && module_deny_chk + if [ "$l_mdir" = "/lib/modules/$(uname -r)/kernel/$l_mtype" ]; then + module_loadable_chk + module_loaded_chk + fi + else + l_output="$l_output\n - module: \"$l_mname\" doesn't exist in \"$l_mdir\"" + fi +done +# Report results. If no failures output in l_output2, we pass +[ -n "$l_output3" ] && echo -e "\n\n -- INFO --\n - module: \"$l_mname\" exists in:$l_output3" +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.2.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.2.3.sh new file mode 100644 index 0000000..8542840 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.2.3.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +l_output="" l_output2="" l_output3="" l_dl="" # Unset output variables +l_mname="rds" # set module name +l_mtype="net" # set module type +#replaced in original script to avoid wildcard +l_searchloc=$(find $(for dir in /lib/modprobe.d /usr/local/lib/modprobe.d /run/modprobe.d /etc/modprobe.d; do [[ -d "$dir" ]] && echo "$dir"; done) -type f -name "*.conf" 2>/dev/null) +#replaced in original script to avoid globstar operator +l_mpath=$(find /lib/modules/ -type d -name $l_mtype) +l_mpname="$(tr '-' '_' <<<"$l_mname")" +l_mndir="$(tr '-' '/' <<<"$l_mname")" +module_loadable_chk() { + # Check if the module is currently loadable + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi +} +module_loaded_chk() { + # Check if the module is currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi +} +module_deny_chk() { + # Check if the module is deny listed + l_dl="y" + if modprobe --showconfig | grep -Pq -- '^\h*blacklist\h+'"$l_mpname"'\b'; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pls -- "^\h*blacklist\h+$l_mname\b" $l_searchloc)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +# Check if the module exists on the system +for l_mdir in $l_mpath; do + if [ -d "$l_mdir/$l_mndir" ] && [ -n "$(ls -A $l_mdir/$l_mndir)" ]; then + l_output3="$l_output3\n - \"$l_mdir\"" + [ "$l_dl" != "y" ] && module_deny_chk + if [ "$l_mdir" = "/lib/modules/$(uname -r)/kernel/$l_mtype" ]; then + module_loadable_chk + module_loaded_chk + fi + else + l_output="$l_output\n - module: \"$l_mname\" doesn't exist in \"$l_mdir\"" + fi +done +# Report results. If no failures output in l_output2, we pass +[ -n "$l_output3" ] && echo -e "\n\n -- INFO --\n - module: \"$l_mname\" exists in:$l_output3" +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.2.4.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.2.4.sh new file mode 100644 index 0000000..65814a1 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.2.4.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +l_output="" l_output2="" l_output3="" l_dl="" # Unset output variables +l_mname="sctp" # set module name +l_mtype="net" # set module type +#replaced in original script to avoid wildcard +l_searchloc=$(find $(for dir in /lib/modprobe.d /usr/local/lib/modprobe.d /run/modprobe.d /etc/modprobe.d; do [[ -d "$dir" ]] && echo "$dir"; done) -type f -name "*.conf" 2>/dev/null) +#replaced in original script to avoid globstar operator +l_mpath=$(find /lib/modules/ -type d -name $l_mtype) +l_mpname="$(tr '-' '_' <<<"$l_mname")" +l_mndir="$(tr '-' '/' <<<"$l_mname")" +module_loadable_chk() { + # Check if the module is currently loadable + l_loadable="$(modprobe -n -v "$l_mname")" + [ "$(wc -l <<<"$l_loadable")" -gt "1" ] && l_loadable="$(grep -P -- "(^\h*install|\b$l_mname)\b" <<<"$l_loadable")" + if grep -Pq -- '^\h*install \/bin\/(true|false)' <<<"$l_loadable"; then + l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\"" + fi +} +module_loaded_chk() { + # Check if the module is currently loaded + if ! lsmod | grep "$l_mname" >/dev/null 2>&1; then + l_output="$l_output\n - module: \"$l_mname\" is not loaded" + else + l_output2="$l_output2\n - module: \"$l_mname\" is loaded" + fi +} +module_deny_chk() { + # Check if the module is deny listed + l_dl="y" + if modprobe --showconfig | grep -Pq -- '^\h*blacklist\h+'"$l_mpname"'\b'; then + l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pls -- "^\h*blacklist\h+$l_mname\b" $l_searchloc)\"" + else + l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed" + fi +} +# Check if the module exists on the system +for l_mdir in $l_mpath; do + if [ -d "$l_mdir/$l_mndir" ] && [ -n "$(ls -A $l_mdir/$l_mndir)" ]; then + l_output3="$l_output3\n - \"$l_mdir\"" + [ "$l_dl" != "y" ] && module_deny_chk + if [ "$l_mdir" = "/lib/modules/$(uname -r)/kernel/$l_mtype" ]; then + module_loadable_chk + module_loaded_chk + fi + else + l_output="$l_output\n - module: \"$l_mname\" doesn't exist in \"$l_mdir\"" + fi +done +# Report results. If no failures output in l_output2, we pass +[ -n "$l_output3" ] && echo -e "\n\n -- INFO --\n - module: \"$l_mname\" exists in:$l_output3" +if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n ** PASS **\n$l_output\n" +else + echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n" + [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n" +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.3.1.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.3.1.sh new file mode 100644 index 0000000..166442a --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.3.1.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +kernel_parameters=("net.ipv4.ip_forward" "net.ipv6.conf.all.forwarding") +kernel_values=("0" "0") +len=${#kernel_parameters[@]} +for ((i = 0; i < len; i++)); do + param=${kernel_parameters[$i]} + value=${kernel_values[$i]} + current_value=$(sysctl -n "$param" 2>/dev/null) + + # Check if sysctl command was successful + if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $param does not exist or could not be retrieved." + exit 1 + fi + + # Check if the current value matches the expected value + if [ "$current_value" == "$value" ]; then + echo "Kernel parameter $param is set correctly to $value." + else + echo "Kernel parameter $param is not set to $value (current value: $current_value)." + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.3.10.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.3.10.sh new file mode 100644 index 0000000..b0a3201 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.3.10.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +kernel_parameter="net.ipv4.tcp_syncookies" +kernel_value="1" +current_value=$(sysctl -n "$kernel_parameter" 2>/dev/null) + +if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $kernel_parameter does not exist or could not be retrieved." + exit 1 +fi + +if [ "$current_value" == "$kernel_value" ]; then + echo "Kernel parameter $kernel_parameter is set to $kernel_value" + exit 0 +else + echo "Kernel parameter $kernel_parameter is not set to $kernel_value (current value: $current_value)" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.3.11.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.3.11.sh new file mode 100644 index 0000000..c4bb189 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.3.11.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +kernel_parameters=("net.ipv6.conf.all.accept_ra" "net.ipv6.conf.default.accept_ra") +kernel_values=("0" "0") +len=${#kernel_parameters[@]} +for ((i = 0; i < len; i++)); do + param=${kernel_parameters[$i]} + value=${kernel_values[$i]} + current_value=$(sysctl -n "$param" 2>/dev/null) + + # Check if sysctl command was successful + if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $param does not exist or could not be retrieved." + exit 1 + fi + + # Check if the current value matches the expected value + if [ "$current_value" == "$value" ]; then + echo "Kernel parameter $param is set correctly to $value." + else + echo "Kernel parameter $param is not set to $value (current value: $current_value)." + exit 1 + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.3.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.3.2.sh new file mode 100644 index 0000000..4a0b392 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.3.2.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +kernel_parameters=("net.ipv4.conf.all.send_redirects" "net.ipv4.conf.default.send_redirects") +kernel_values=("0" "0") +len=${#kernel_parameters[@]} +for ((i = 0; i < len; i++)); do + param=${kernel_parameters[$i]} + value=${kernel_values[$i]} + current_value=$(sysctl -n "$param" 2>/dev/null) + + # Check if sysctl command was successful + if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $param does not exist or could not be retrieved." + exit 1 + fi + + # Check if the current value matches the expected value + if [ "$current_value" == "$value" ]; then + echo "Kernel parameter $param is set correctly to $value." + else + echo "Kernel parameter $param is not set to $value (current value: $current_value)." + exit 1 + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.3.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.3.3.sh new file mode 100644 index 0000000..1be5056 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.3.3.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +kernel_parameter="net.ipv4.icmp_ignore_bogus_error_responses" +kernel_value="1" +current_value=$(sysctl -n "$kernel_parameter" 2>/dev/null) + +if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $kernel_parameter does not exist or could not be retrieved." + exit 1 +fi + +if [ "$current_value" == "$kernel_value" ]; then + echo "Kernel parameter $kernel_parameter is set to $kernel_value" + exit 0 +else + echo "Kernel parameter $kernel_parameter is not set to $kernel_value (current value: $current_value)" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.3.4.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.3.4.sh new file mode 100644 index 0000000..fc0cdb4 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.3.4.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +kernel_parameter="net.ipv4.icmp_echo_ignore_broadcasts" +kernel_value="1" + +current_value=$(sysctl -n "$kernel_parameter" 2>/dev/null) + +if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $kernel_parameter does not exist or could not be retrieved." + exit 1 +fi + +if [ "$current_value" == "$kernel_value" ]; then + echo "Kernel parameter $kernel_parameter is set to $kernel_value" + exit 0 +else + echo "Kernel parameter $kernel_parameter is not set to $kernel_value (current value: $current_value)" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.3.5.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.3.5.sh new file mode 100644 index 0000000..f04bdbc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.3.5.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +kernel_parameters=("net.ipv4.conf.all.accept_redirects" "net.ipv4.conf.default.accept_redirects" "net.ipv6.conf.all.accept_redirects" "net.ipv6.conf.default.accept_redirects") +kernel_values=("0" "0" "0" "0") +len=${#kernel_parameters[@]} +for ((i = 0; i < len; i++)); do + param=${kernel_parameters[$i]} + value=${kernel_values[$i]} + current_value=$(sysctl -n "$param" 2>/dev/null) + + # Check if sysctl command was successful + if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $param does not exist or could not be retrieved." + exit 1 + fi + + # Check if the current value matches the expected value + if [ "$current_value" == "$value" ]; then + echo "Kernel parameter $param is set correctly to $value." + else + echo "Kernel parameter $param is not set to $value (current value: $current_value)." + exit 1 + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.3.6.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.3.6.sh new file mode 100644 index 0000000..d9d1bec --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.3.6.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +kernel_parameters=("net.ipv4.conf.default.secure_redirects" "net.ipv4.conf.all.secure_redirects") +kernel_values=("0" "0") +len=${#kernel_parameters[@]} +for ((i = 0; i < len; i++)); do + param=${kernel_parameters[$i]} + value=${kernel_values[$i]} + current_value=$(sysctl -n "$param" 2>/dev/null) + + # Check if sysctl command was successful + if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $param does not exist or could not be retrieved." + exit 1 + fi + + # Check if the current value matches the expected value + if [ "$current_value" == "$value" ]; then + echo "Kernel parameter $param is set correctly to $value." + else + echo "Kernel parameter $param is not set to $value (current value: $current_value)." + exit 1 + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.3.7.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.3.7.sh new file mode 100644 index 0000000..f7af3f9 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.3.7.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +kernel_parameters=("net.ipv4.conf.all.rp_filter" "net.ipv4.conf.default.rp_filter") +kernel_values=("1" "1") +len=${#kernel_parameters[@]} +for ((i = 0; i < len; i++)); do + param=${kernel_parameters[$i]} + value=${kernel_values[$i]} + current_value=$(sysctl -n "$param" 2>/dev/null) + + # Check if sysctl command was successful + if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $param does not exist or could not be retrieved." + exit 1 + fi + + # Check if the current value matches the expected value + if [ "$current_value" == "$value" ]; then + echo "Kernel parameter $param is set correctly to $value." + else + echo "Kernel parameter $param is not set to $value (current value: $current_value)." + exit 1 + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.3.8.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.3.8.sh new file mode 100644 index 0000000..6850679 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.3.8.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +kernel_parameters=("net.ipv4.conf.all.accept_source_route" "net.ipv4.conf.default.accept_source_route" "net.ipv6.conf.all.accept_source_route" "net.ipv6.conf.default.accept_source_route") +kernel_values=("0" "0" "0" "0") +len=${#kernel_parameters[@]} +for ((i = 0; i < len; i++)); do + param=${kernel_parameters[$i]} + value=${kernel_values[$i]} + current_value=$(sysctl -n "$param" 2>/dev/null) + + # Check if sysctl command was successful + if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $param does not exist or could not be retrieved." + exit 1 + fi + + # Check if the current value matches the expected value + if [ "$current_value" == "$value" ]; then + echo "Kernel parameter $param is set correctly to $value." + else + echo "Kernel parameter $param is not set to $value (current value: $current_value)." + exit 1 + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/common/3.3.9.sh b/ATAPAuditor/Helpers/ShellScripts/common/3.3.9.sh new file mode 100644 index 0000000..33c9968 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/3.3.9.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +kernel_parameters=("net.ipv4.conf.all.log_martians" "net.ipv4.conf.default.log_martians") +kernel_values=("1" "1") +len=${#kernel_parameters[@]} +for ((i = 0; i < len; i++)); do + param=${kernel_parameters[$i]} + value=${kernel_values[$i]} + current_value=$(sysctl -n "$param" 2>/dev/null) + + # Check if sysctl command was successful + if [ $? -ne 0 ]; then + echo "Error: Kernel parameter $param does not exist or could not be retrieved." + exit 1 + fi + + # Check if the current value matches the expected value + if [ "$current_value" == "$value" ]; then + echo "Kernel parameter $param is set correctly to $value." + else + echo "Kernel parameter $param is not set to $value (current value: $current_value)." + exit 1 + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.1.16.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.1.16.sh new file mode 100644 index 0000000..c745626 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.1.16.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +parameter_sshd_t=maxauthtries +parameter_sshd_config=MaxAuthTries +desired_value=4 + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config; then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + else + echo "$parameter_sshd_config not set in sshd_config, using default" + exit 1 + fi +fi + +if [ "$actual_value" -le "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.1.19.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.1.19.sh new file mode 100644 index 0000000..164bac4 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.1.19.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +parameter_sshd_t=permitemptypasswords +parameter_sshd_config=PermitEmptyPasswords +desired_value=no + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq "^$parameter_sshd_config" /etc/ssh/sshd_config; then + actual_value=$(grep "^$parameter_sshd_config" /etc/ssh/sshd_config | awk '{print $2}') + else + echo "$parameter_sshd_config not set in sshd_config, using default" + exit 1 + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.1.20.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.1.20.sh new file mode 100644 index 0000000..d525c6b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.1.20.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +parameter_sshd_t=permitrootlogin +parameter_sshd_config=PermitRootLogin +desired_value=no + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config; then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + else + + exit 1 + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.1.21.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.1.21.sh new file mode 100644 index 0000000..b8f5269 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.1.21.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +parameter_sshd_t=permituserenvironment +parameter_sshd_config=PermitUserEnvironment +desired_value=no + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq "^$parameter_sshd_config" /etc/ssh/sshd_config; then + actual_value=$(grep "^$parameter_sshd_config" /etc/ssh/sshd_config | awk '{print $2}') + else + exit 1 + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.1.22.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.1.22.sh new file mode 100644 index 0000000..8c684c1 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.1.22.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +parameter_sshd_t=usepam +parameter_sshd_config=UsePAM +desired_value=yes + +if ! command -v sshd &>/dev/null; then + echo "sshd command could not be found" + exit 0 +fi + +# Check using sshd -T output +actual_value=$(sshd -T | grep -i "$parameter_sshd_t" | awk '{print $2}') + +if [ -z "$actual_value" ]; then + if grep -iq '^$parameter_sshd_config' /etc/ssh/sshd_config; then + actual_value=$(grep -i '^$parameter_sshd_config' /etc/ssh/sshd_config | awk '{print $2}') + else + + exit 1 + fi +fi + +if [ "$actual_value" = "$desired_value" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.1.3.sh new file mode 100644 index 0000000..23be640 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.1.3.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +pmask="0133" +maxperm="$(printf '%o' $((0777 & ~$pmask)))" + +find -L /etc/ssh -type f 2>/dev/null | while IFS= read -r file; do + if ssh-keygen -lf "$file" &>/dev/null && file "$file" | grep -qi 'OpenSSH.*public key'; then + read -r mode owner group < <(stat -Lc '%#a %U %G' "$file") + [ $((mode & pmask)) -gt 0 ] && exit 1 + [ "$owner" != "root" ] && exit 1 + [ "$group" != "root" ] && exit 1 + fi +done diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.2.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.2.2.sh new file mode 100644 index 0000000..e41a341 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.2.2.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +# Simplified pattern +pattern="Defaults use_pty" + +# Check if the pattern exists in /etc/sudoers +if grep -E "^\s*Defaults\s+use_pty" /etc/sudoers >/dev/null; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.2.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.2.3.sh new file mode 100644 index 0000000..9c958aa --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.2.3.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +PATTERN="^\h*Defaults\h+([^#]+,\h*)?logfile\h*=\h*(\"|\')?\H+(\"|\')?(,\h*\H+\h*)*\h*(#.*)?$" +FILES='/etc/sudoers*' + +if grep -rPsi "$PATTERN" $FILES >/dev/null 2>&1; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.2.6.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.2.6.sh new file mode 100644 index 0000000..510f285 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.2.6.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +timeout=$(grep -roP "timestamp_timeout=\K[0-9]*" /etc/sudoers* | grep -v "/etc/sudoers.bak") + +if [ -n "$timeout" ]; then + timeout=$(echo "$timeout" | grep -oP "[0-9]+$") +fi + +if [ -z "$timeout" ]; then + timeout=$(sudo -V | grep -oP "(?<=Authentication timestamp timeout: )\d+") +fi + +if [ -z "$timeout" ]; then + timeout=0 +fi + +timeout=${timeout:-0} + +if [ "$timeout" -le 15 ] && [ "$timeout" -gt 0 ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.1.1.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.1.1.sh new file mode 100644 index 0000000..19eec99 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.1.1.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +faillock_conf="/etc/security/faillock.conf" +expected_value=5 +if grep -Pq '^\s*#?\s*deny\s*=\s*([0-9]+)' "$faillock_conf"; then + current_value=$(grep -Eo '^\s*#?\s*deny\s*=\s*([0-9]+)' "$faillock_conf" | awk -F'=' '{print $2}' | tr -d ' ') +else + echo "ERROR: deny is not set in $faillock_conf." + exit 1 +fi +if ((current_value <= expected_value)); then + exit 0 +else + echo "ERROR: deny=$current_value is higher than $expected_value" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.1.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.1.2.sh new file mode 100644 index 0000000..2c84f13 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.1.2.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +faillock_conf="/etc/security/faillock.conf" +expected_value=900 +value="unlock_time" +regex_pattern="^\s*#*\s*${value}\s*=\s*[0-9]+" + +if grep -Eq "$regex_pattern" "$faillock_conf"; then + current_value=$(grep -E "$regex_pattern" "$faillock_conf" | head -n 1 | sed -E "s/.*=\s*([0-9]+)/\1/" | tr -d ' ') + if [[ $current_value =~ ^# ]]; then + echo "ERROR: The line is commented out" + exit 1 + fi + if ((current_value < expected_value)); then + echo "ERROR: unlock_time = $current_value < $expected_value" + exit 1 + else + exit 0 + fi +else + echo "ERROR: No such line found for unlock_time in $faillock_conf" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.1.3.sh new file mode 100644 index 0000000..0b03ba8 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.1.3.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +faillock_conf="/etc/security/faillock.conf" +limit_value=60 + +if grep -Eq "^\s*even_deny_root\s*" "$faillock_conf"; then + echo "Test passed: even_deny_root is correctly enabled." +else + echo "ERROR: even_deny_root is missing or commented out." + exit 1 +fi + +if grep -Eq "^\s*root_unlock_time\s*=\s*[0-9]+\s*" "$faillock_conf"; then + current_value=$(grep -Eo "^\s*root_unlock_time\s*=\s*[0-9]+" "$faillock_conf" | awk -F'=' '{print $2}' | tr -d ' ') + if ((current_value >= limit_value)); then + echo "Test passed: root_unlock_time=$current_value is correctly set." + else + echo "ERROR: root_unlock_time=$current_value is less than $limit_value." + exit 1 + fi +else + echo "ERROR: root_unlock_time is missing or commented out." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.1.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.1.sh new file mode 100644 index 0000000..8596d69 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.1.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# Configuration file to check +FILE="/etc/security/pwquality.conf" +# Pattern to search for +PATTERN="difok" + +# Check if the configuration file exists +if [ ! -f "$FILE" ]; then + echo "File $FILE not found." + exit 1 +fi + +# Search for the pattern, whether it's commented or not +grep -E "^[[:space:]]*#?[[:space:]]*$PATTERN\b" "$FILE" >/dev/null +FOUND=$? + +# If the pattern is found +if [ $FOUND -eq 0 ]; then + # Check if the pattern is commented + grep -E "^[[:space:]]*#[[:space:]]*$PATTERN\b" "$FILE" >/dev/null + COMMENTED=$? + + if [ $COMMENTED -eq 0 ]; then + echo "Pattern $PATTERN is commented." + exit 1 + fi + + # Extract the value of difok using grep and sed + VALUE=$(grep -E "^[[:space:]]*$PATTERN\s*=\s*[0-9]+" "$FILE" | sed -E 's/.*=\s*([0-9]+).*/\1/') + + # If the value was found and it's a valid number + if [[ -n "$VALUE" ]]; then + # Compare the extracted value with 2 + if [ "$VALUE" -lt 2 ]; then + echo "The value of $PATTERN ($VALUE) is less than 2." + exit 1 + else + echo "The value of $PATTERN ($VALUE) is valid (>= 2)." + exit 0 + fi + else + echo "No valid value for $PATTERN found." + exit 1 + fi +else + echo "Pattern $PATTERN not found." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.2.sh new file mode 100644 index 0000000..1c25ca4 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.2.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# Configuration file to check +FILE="/etc/security/pwquality.conf" +# Pattern to search for +PATTERN="minlen" + +# Check if the configuration file exists +if [ ! -f "$FILE" ]; then + echo "File $FILE not found." + exit 1 +fi + +# Search for the pattern, whether it's commented or not +grep -E "^[[:space:]]*#?[[:space:]]*$PATTERN\b" "$FILE" >/dev/null +FOUND=$? + +# If the pattern is found +if [ $FOUND -eq 0 ]; then + # Check if the pattern is commented + grep -E "^[[:space:]]*#[[:space:]]*$PATTERN\b" "$FILE" >/dev/null + COMMENTED=$? + + if [ $COMMENTED -eq 0 ]; then + echo "Pattern $PATTERN is commented." + exit 1 + fi + + # Extract the value of minlen using grep and sed + VALUE=$(grep -E "^[[:space:]]*$PATTERN\s*=\s*[0-9]+" "$FILE" | sed -E 's/.*=\s*([0-9]+).*/\1/') + + # If the value was found and it's a valid number + if [[ -n "$VALUE" ]]; then + # Compare the extracted value with 14 + if [ "$VALUE" -lt 14 ]; then + echo "The value of $PATTERN ($VALUE) is less than 14." + exit 1 + else + echo "The value of $PATTERN ($VALUE) is valid (>= 14)." + exit 0 + fi + else + echo "No valid value for $PATTERN found." + exit 1 + fi +else + echo "Pattern $PATTERN not found." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.4.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.4.sh new file mode 100644 index 0000000..e27b2ae --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.4.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Configuration file to check +FILE="/etc/security/pwquality.conf" +# Pattern to search for +PATTERN="maxrepeat" + +# Check if the configuration file exists +if [ ! -f "$FILE" ]; then + echo "File $FILE not found." + exit 1 +fi + +# Search for the pattern, whether it's commented or not +grep -E "^\s*#?\s*$PATTERN\b" "$FILE" >/dev/null +FOUND=$? + +# If the pattern is found +if [ $FOUND -eq 0 ]; then + # Check if the pattern is commented + grep -E "^\s*#\s*$PATTERN\b" "$FILE" >/dev/null + COMMENTED=$? + + if [ $COMMENTED -eq 0 ]; then + echo "Pattern $PATTERN is commented." + exit 1 + fi + + # Extract the value of maxrepeat using grep and sed + VALUE=$(grep -E "^\s*$PATTERN\s*=\s*[0-9]+" "$FILE" | sed -E 's/.*=\s*([0-9]+).*/\1/') + + # If the value was found and it's a valid number + if [[ -n "$VALUE" ]]; then + # Compare the extracted value with 3 + if [ "$VALUE" -gt 3 ] || [ "$VALUE" -eq 0 ]; then + echo "The value of $PATTERN ($VALUE) is greather than 3 or equal to 0." + exit 1 + else + echo "The value of $PATTERN ($VALUE) is valid (<3 und >0)." + exit 0 + fi + else + echo "No valid value for $PATTERN found." + exit 1 + fi +else + echo "Pattern $PATTERN not found." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.5.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.5.sh new file mode 100644 index 0000000..f3f1dc8 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.5.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# Configuration file to check +FILE="/etc/security/pwquality.conf" +# Pattern to search for +PATTERN="maxsequence" + +# Check if the configuration file exists +if [ ! -f "$FILE" ]; then + echo "File $FILE not found." + exit 1 +fi + +# Search for the pattern, whether it's commented or not +grep -E "^\s*#?\s*$PATTERN\b" "$FILE" >/dev/null +FOUND=$? + +# If the pattern is found +if [ $FOUND -eq 0 ]; then + # Check if the pattern is commented + grep -E "^\s*#\s*$PATTERN\b" "$FILE" >/dev/null + COMMENTED=$? + + if [ $COMMENTED -eq 0 ]; then + echo "Pattern $PATTERN is commented." + exit 1 + fi + + # Extract the value of maxsequence using grep and sed + VALUE=$(grep -E "^\s*$PATTERN\s*=\s*[0-9]+" "$FILE" | sed -E 's/.*=\s*([0-9]+).*/\1/') + + # If the value was found and it's a valid number + if [[ -n "$VALUE" ]]; then + # Compare the extracted value with 3 + if [ "$VALUE" -gt 3 ] || [ "$VALUE" -eq 0 ]; then + echo "The value of $PATTERN ($VALUE) is greather than 3 or equal to 0." + exit 1 + else + echo "The value of $PATTERN ($VALUE) is valid (<3 und >0)." + exit 0 + fi + else + echo "No valid value for $PATTERN found." + exit 1 + fi +else + echo "Pattern $PATTERN not found." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.6.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.6.sh new file mode 100644 index 0000000..cae1141 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.2.6.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Configuration file to check +FILE="/etc/security/pwquality.conf" +# Pattern to search for +PATTERN="dictcheck" + +# Check if the configuration file exists +if [ ! -f "$FILE" ]; then + echo "File $FILE not found." + exit 1 +fi + +# Search for the pattern, whether it's commented or not +grep -E "^\s*#?\s*$PATTERN\b" "$FILE" >/dev/null +FOUND=$? + +# If the pattern is found +if [ $FOUND -eq 0 ]; then + # Check if the pattern is commented + grep -E "^\s*#\s*$PATTERN\b" "$FILE" >/dev/null + COMMENTED=$? + + if [ $COMMENTED -eq 0 ]; then + echo "Pattern $PATTERN is commented." + exit 1 + fi + + # Extract the value of dictcheck using grep and sed + VALUE=$(grep -E "^\s*$PATTERN\s*=\s*[0-9]+" "$FILE" | sed -E 's/.*=\s*([0-9]+).*/\1/') + + # If the value was found and it's a valid number + if [[ -n "$VALUE" ]]; then + # Compare the extracted value with 1 + if [ "$VALUE" -ne 1 ] || [ "$VALUE" -eq 0 ]; then + echo "The value of $PATTERN ($VALUE) is not the best or egal to 0. Updating to $R_VALUE." + exit 1 + else + echo "The value of $PATTERN ($VALUE) is valid (dictcheck = 1)." + exit 0 + fi + else + echo "No valid value for $PATTERN found." + exit 1 + fi +else + echo "Pattern $PATTERN not found." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.3.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.3.3.sh new file mode 100644 index 0000000..5e0bb2c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.3.3.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +files_to_check=$(awk '/Password-Type:/{ f = 1;next } /-Type:/{ f = 0 } f {if (/pam_pwhistory\.so/) print FILENAME}' /usr/share/pam-configs/*) +if [[ -z $files_to_check ]]; then + echo "file was not found" +else + for file in "$files_to_check"; do + if grep -Eq "pam_pwhistory\.so.*use_authtok" "$file"; then + exit 0 + else + exit 1 + fi + done + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.4.1.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.4.1.sh new file mode 100644 index 0000000..b05ee3e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.4.1.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +files_to_check=$(grep -El 'pam_unix\.so\s+([^#\s]+\s+)?nullok\b' /usr/share/pam-configs/*) +if [[ -z "$files_to_check" ]]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.4.4.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.4.4.sh new file mode 100644 index 0000000..ba88210 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.3.3.4.4.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +files_to_check=$(grep -Elz "Password-Type:.*\n.*pam_unix\.so" /usr/share/pam-configs/*) +if [ -z "$files_to_check" ]; then + echo "No relevant files found." + exit 0 +fi + +for file in $files_to_check; do + if ! grep -Eq "pam_unix\.so.*use_authtok" "$file"; then + exit 1 + fi +done +exit 0 + diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.1.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.1.sh new file mode 100644 index 0000000..e9d4f78 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.1.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# Configuration file to check +FILE="/etc/login.defs" +# Pattern to search for +PATTERN="PASS_MAX_DAYS" + +# Check if the configuration file exists +if [ ! -f "$FILE" ]; then + echo "File $FILE not found." + exit 1 +fi + +# Search for the pattern, whether it's commented or not +grep -E "^\s*#?\s*$PATTERN\b" "$FILE" >/dev/null +FOUND=$? + +# If the pattern is found +if [ $FOUND -eq 0 ]; then + # Check if the pattern is commented + grep -E "^#\s*$PATTERN\s+[0-9]+" "$FILE" >/dev/null + COMMENTED=$? + + if [ $COMMENTED -eq 0 ]; then + echo "Pattern $PATTERN is commented." + exit 1 + fi + + # Extract the value of PASS_MAX_DAYS using grep and sed + VALUE=$(grep -E "^#?\s*$PATTERN\s+[0-9]+" "$FILE" | sed -E 's/[^0-9]*([0-9]+).*/\1/') + + # If the value was found and it's a valid number + if [[ -n "$VALUE" ]]; then + # Compare the extracted value with 365 + if [ "$VALUE" -gt 365 ] || [ "$VALUE" -eq 0 ]; then + echo "The value of $PATTERN ($VALUE) is greather than 365 or egal to 0." + exit 1 + else + echo "The value of $PATTERN ($VALUE) is valid (<=365)." + exit 0 + fi + else + echo "No valid value for $PATTERN found." + exit 1 + fi +else + echo "Pattern $PATTERN not found." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.2.sh new file mode 100644 index 0000000..1dfaa45 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.2.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Configuration file to check +FILE="/etc/login.defs" +# Pattern to search for +PATTERN="PASS_MIN_DAYS" + +# Check if the configuration file exists +if [ ! -f "$FILE" ]; then + echo "File $FILE not found." + exit 1 +fi + +# Search for the pattern, whether it's commented or not +grep -E "^\s*#?\s*$PATTERN\b" "$FILE" >/dev/null +FOUND=$? + +# If the pattern is found +if [ $FOUND -eq 0 ]; then + # Check if the pattern is commented + grep -E "^#\s*$PATTERN\s+[0-9]+" "$FILE" >/dev/null + COMMENTED=$? + + if [ $COMMENTED -eq 0 ]; then + echo "Pattern $PATTERN is commented." + exit 1 + fi + + # Extract the value of PASS_MIN_DAYS using grep and sed + VALUE=$(grep -E "^[[:space:]]*$PATTERN\s*=?\s*[0-9]+" "$FILE" | sed -E 's/[^0-9]*([0-9]+).*/\1/') + + # If the value was found and it's a valid number + if [[ -n "$VALUE" ]]; then + # Compare the extracted value with 0 + if [ "$VALUE" -le 0 ]; then + echo "The value of $PATTERN ($VALUE) is less than 0 or egal to 0." + exit 1 + else + echo "The value of $PATTERN ($VALUE) is valid (>=0)." + exit 0 + fi + else + echo "No valid value for $PATTERN found." + exit 1 + fi +else + echo "Pattern $PATTERN not found." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.3.sh new file mode 100644 index 0000000..da7c69b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.3.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Configuration file to check +FILE="/etc/login.defs" +# Pattern to search for +PATTERN="PASS_WARN_AGE" + +# Check if the configuration file exists +if [ ! -f "$FILE" ]; then + echo "File $FILE not found." + exit 1 +fi + +# Search for the pattern, whether it's commented or not +grep -E "^\s*#?\s*$PATTERN\b" "$FILE" >/dev/null +FOUND=$? + +# If the pattern is found +if [ $FOUND -eq 0 ]; then + # Check if the pattern is commented + grep -E "^#\s*$PATTERN\s+[0-9]+" "$FILE" >/dev/null + COMMENTED=$? + + if [ $COMMENTED -eq 0 ]; then + echo "Pattern $PATTERN is commented." + exit 1 + fi + + # Extract the value of PASS_WARN_AGE using grep and sed + VALUE=$(grep -E "^#?\s*$PATTERN\s+[0-9]+" "$FILE" | sed -E 's/[^0-9]*([0-9]+).*/\1/') + + # If the value was found and it's a valid number + if [[ -n "$VALUE" ]]; then + # Compare the extracted value with 7 + if [ "$VALUE" -lt 7 ]; then + echo "The value of $PATTERN ($VALUE) is less than 7 ." + exit 1 + else + echo "The value of $PATTERN ($VALUE) is valid (>=7)." + exit 0 + fi + else + echo "No valid value for $PATTERN found." + exit 1 + fi +else + echo "Pattern $PATTERN not found." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.4.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.4.sh new file mode 100644 index 0000000..448c3d7 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.4.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# Configuration file to check +FILE="/etc/login.defs" +# Pattern to search for +PATTERN="ENCRYPT_METHOD" + +# Check if the configuration file exists +if [ ! -f "$FILE" ]; then + echo "File $FILE not found." + exit 1 +fi + +# Search for the pattern, whether it's commented or not +grep -Eq "^#?\s*$PATTERN\s+\S+$" "$FILE" +FOUND=$? + +# If the pattern is found +if [ $FOUND -eq 0 ]; then + # Check if the pattern is commented + + grep -Eq "^#\s*$PATTERN\s+\S+$" "$FILE" + COMMENTED=$? + + if [ $COMMENTED -eq 0 ]; then + echo "Pattern $PATTERN is commented." + exit 1 + fi + + line=$(grep -E "^\s*$PATTERN\s+\S+$" "$FILE") + if [ -n "$line" ]; then + word=$(echo "$line" | awk '{print $2}') + fi + + if [[ -n "$word" ]]; then + # Compare the extracted word with SHA512 UND YESCRYPT + VALUE1="SHA512" + VALUE2="YESCRYPT" + + if [ "$word" != "$VALUE1" ] && [ "$word" != "$VALUE2" ]; then + echo "The value of $PATTERN ($word) is not good." + exit 1 + else + echo "The value of $PATTERN ($word) is valid (equal to SHA512 or YESCRYPT). No changes needed." + exit 0 + fi + else + echo "No valid value for $PATTERN found." + exit 1 + fi + +else + + echo "Pattern $PATTERN not found." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.5.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.5.sh new file mode 100644 index 0000000..971500c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.4.1.5.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +expected_inactive_days=45 + +if useradd -D | grep -Eq '^\s*INACTIVE\s*=\s*'$expected_inactive_days'\b'; then + echo "Default inactivity period is correct." +else + echo "Default inactivity period is incorrect." + exit 1 +fi + +while IFS=: read -r username password lastchg min max warn inactive_days expire; do + if [[ -z "$inactive_days" || "$inactive_days" == " " ]]; then + continue + fi + + if [[ "$inactive_days" -gt $expected_inactive_days ]]; then + echo "User $username exceeds policy." + exit 1 + fi +done /dev/null +FOUND=$? + +if [ $FOUND -eq 0 ]; then + + echo "The line containing '$PATTERN' is in the File $FILE." + exit 1 +else + echo "$PATTERN is not in the File or not Found" + exit 0 + +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.4.3.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.4.3.2.sh new file mode 100644 index 0000000..66f3e7c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.4.3.2.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +tmout=$(grep 'typeset -xr TMOUT=900' -- /etc/bashrc /etc/profile /etc/profile.d/*.sh 2>/dev/null) +if [[ -n "$tmout" ]]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/5.4.3.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/5.4.3.3.sh new file mode 100644 index 0000000..762b687 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/5.4.3.3.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +for file in /etc/profile.d/*.sh; do + if grep -P '^\s*umask\s+0027' "$file" &>/dev/null; then + exit 0 + fi +done + +exit 1 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.1.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.1.3.sh new file mode 100644 index 0000000..ff0893c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.1.3.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +config_file="/etc/aide/aide.conf" +pattern=("/sbin/auditctl" "/sbin/auditd" "/sbin/ausearch" "/sbin/aureport" "/sbin/autrace" "/sbin/augenrules") +if [ ! -f "$config_file" ]; then + exit 0 +fi + +for line in "${pattern[@]}"; do + regex_pattern="^\s*#*\s*${line}\b" + if ! grep -Eq "$regex_pattern" "$config_file"; then + exit 1 + fi +done +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.2.1.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.2.1.sh new file mode 100644 index 0000000..738e15e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.2.1.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# Path to the auditd configuration file +AUDITD_CONF="/etc/audit/auditd.conf" + +# Check if the file exists +if [[ -f "$AUDITD_CONF" ]]; then + # Use grep to search for the pattern + if grep -qE "^max_log_file[[:space:]]*=[[:space:]]*[0-9]+" "$AUDITD_CONF"; then + exit 0 + else + exit 1 + fi +else + echo "File $AUDITD_CONF does not exist." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.2.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.2.2.sh new file mode 100644 index 0000000..59310ea --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.2.2.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# Path to the auditd configuration file +AUDITD_CONF="/etc/audit/auditd.conf" + +# Check if the file exists +if [[ -f "$AUDITD_CONF" ]]; then + # Use grep to search for the exact line + if grep -q "^max_log_file_action[[:space:]]*=[[:space:]]*keep_logs" "$AUDITD_CONF"; then + exit 0 + else + exit 1 + fi +else + echo "File $AUDITD_CONF does not exist." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.1.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.1.sh new file mode 100644 index 0000000..82d7efc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.1.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +on_disk=$(awk '/^ *-w/ &&/\/etc\/sudoers/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules) + +if [[ -n "$on_disk" ]]; then + exit 0 +else + echo "ERROR: Audit rules are NOT correctly set." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.10.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.10.sh new file mode 100644 index 0000000..68d108c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.10.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + +if [ -n "$UID_MIN" ]; then + on_disk=$(awk "/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -S/ &&/mount/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules) + + if [[ -n "$on_disk" ]]; then + exit 0 + else + exit 1 + fi +else + echo "ERROR: Variable 'UID_MIN' is unset.\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.12.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.12.sh new file mode 100644 index 0000000..52f851b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.12.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +on_disk=$(awk '/^ *-w/ &&(/\/var\/log\/lastlog/ ||/\/var\/run\/faillock/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules) + +if [[ -n "$on_disk" ]]; then + exit 0 +else + echo "ERROR: Audit rules are NOT correctly set." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.13.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.13.sh new file mode 100644 index 0000000..546a654 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.13.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + +if [ -n "$UID_MIN" ]; then + on_disk=$(awk "/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -S/ &&(/unlink/||/rename/||/unlinkat/||/renameat/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules) + + if [[ -n "$on_disk" ]]; then + exit 0 + else + exit 1 + fi +else + echo "ERROR: Variable 'UID_MIN' is unset.\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.14.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.14.sh new file mode 100644 index 0000000..4b7b281 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.14.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +on_disk=$(awk '/^ *-w/ &&(/\/etc\/selinux/ ||/\/usr\/share\/selinux/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules) + +if [[ -n "$on_disk" ]]; then + exit 0 +else + echo "ERROR: Audit rules are NOT correctly set." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.15.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.15.sh new file mode 100644 index 0000000..1a955df --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.15.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + +if [ -n "$UID_MIN" ]; then + on_disk=$(awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/bin\/chcon/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules) + + if [[ -n "$on_disk" ]]; then + exit 0 + else + exit 1 + fi +else + echo "ERROR: Variable 'UID_MIN' is unset.\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.16.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.16.sh new file mode 100644 index 0000000..7fc8af4 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.16.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + +if [ -n "$UID_MIN" ]; then + on_disk=$(awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/bin\/setfacl/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules) + + if [[ -n "$on_disk" ]]; then + exit 0 + else + exit 1 + fi +else + echo "ERROR: Variable 'UID_MIN' is unset.\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.17.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.17.sh new file mode 100644 index 0000000..60136b8 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.17.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + +if [ -n "$UID_MIN" ]; then + on_disk=$(awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/bin\/chacl/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules) + + if [[ -n "$on_disk" ]]; then + exit 0 + else + exit 1 + fi +else + echo "ERROR: Variable 'UID_MIN' is unset.\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.18.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.18.sh new file mode 100644 index 0000000..802d3e6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.18.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + +if [ -n "$UID_MIN" ]; then + on_disk=$(awk "/^ *-a *always,exit/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&/ -F *perm=x/ &&/ -F *path=\/usr\/sbin\/usermod/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules) + + if [[ -n "$on_disk" ]]; then + exit 0 + else + exit 1 + fi +else + echo "ERROR: Variable 'UID_MIN' is unset.\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.19.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.19.sh new file mode 100644 index 0000000..444494e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.19.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + +if [ -n "$UID_MIN" ]; then + on_disk=$(awk '/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&(/ -F auid!=unset/||/ -F auid!=-1/||/ -F auid!=4294967295/) &&/ -S/ &&(/init_module/ ||/finit_module/ ||/delete_module/ ||/create_module/ ||/query_module/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules) + + if [[ -n "$on_disk" ]]; then + exit 0 + else + echo "ERROR: on_disk != loaded" + exit 1 + fi +else + echo "ERROR: Variable 'UID_MIN' is unset.\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.2.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.2.sh new file mode 100644 index 0000000..191d9bc --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.2.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +on_disk=$(awk '/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&(/ -C *euid!=uid/||/ -C *uid!=euid/) &&/ -S *execve/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules) + +if [[ -n "$on_disk" ]]; then + exit 0 +else + echo "ERROR: Audit rules are NOT correctly set." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.3.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.3.sh new file mode 100644 index 0000000..a949cf6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.3.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +SUDO_LOG_FILE=$(grep -r logfile /etc/sudoers* | grep -v "/etc/sudoers.bak" | sed -e 's/.*logfile=//;s/,? .*//' -e 's/"//g') + +if [ -n "$SUDO_LOG_FILE" ]; then + on_disk=$(grep -E "^\s*-w\s+$SUDO_LOG_FILE\s+-p\s+wa" /etc/audit/rules.d/*.rules) + loaded=$(auditctl -l | grep -E "^\s*-w\s+$SUDO_LOG_FILE\s+-p\s+wa") + if [[ -n "$on_disk" && -n "$loaded" ]]; then + echo "Audit rules are correctly set." + exit 0 + else + echo "ERROR: Audit rules are NOT correctly set or loaded." + exit 1 + fi +else + echo "ERROR: Variable 'SUDO_LOG_FILE' is unset or empty." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.4.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.4.sh new file mode 100644 index 0000000..008e93d --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.4.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +on_disk1=$(awk '/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&/ -S/ &&(/adjtimex/ ||/settimeofday/ ||/clock_settime/ ) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules) + +on_disk2=$(awk '/^ *-w/ &&/\/etc\/localtime/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules) + +if [[ -n "$on_disk1" && -n "$on_disk2" ]]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.5.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.5.sh new file mode 100644 index 0000000..49fedb4 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.5.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +on_disk1=$(awk '/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&/ -S/ &&(/sethostname/ ||/setdomainname/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules) + +on_disk2=$(awk '/^ *-w/ &&(/\/etc\/issue/ ||/\/etc\/issue.net/ ||/\/etc\/hosts/ ||/\/etc\/network/ ||/\/etc\/netplan/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules) + +if [[ -n "$on_disk1" && -n "$on_disk2" ]]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.6.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.6.sh new file mode 100644 index 0000000..7e721aa --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.6.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +test_failed=0 +for PARTITION in $(findmnt -n -l -k -it $(awk '/nodev/ { print $2 }' /proc/filesystems | paste -sd,) | grep -Pv "noexec|nosuid" | awk '{print $1}'); do + for PRIVILEGED in $(find "${PARTITION}" -xdev -perm /6000 -type f); do + if grep -qr "${PRIVILEGED}" /etc/audit/rules.d; then + printf "OK: '${PRIVILEGED}' found in on-disk configuration.\n" + else + printf "ERROR: '${PRIVILEGED}' not found in on-disk configuration.\n" + test_failed=1 + fi + done +done + +RUNNING=$(auditctl -l) +if [ -n "${RUNNING}" ]; then + for PARTITION in $(findmnt -n -l -k -it $(awk '/nodev/ { print $2 }' /proc/filesystems | paste -sd,) | grep -Pv "noexec|nosuid" | awk '{print $1}'); do + for PRIVILEGED in $(find "${PARTITION}" -xdev -perm /6000 -type f); do + if printf -- "${RUNNING}" | grep -q "${PRIVILEGED}"; then + printf "OK: '${PRIVILEGED}' found in running configuration.\n" + else + printf "ERROR: '${PRIVILEGED}' not found in running configuration.\n" + test_failed=1 + fi + done + done +else + printf "ERROR: No rules found in running configuration.\n" + test_failed=1 +fi + +# Setze den Exit-Code basierend auf dem Test-Status +if [ "$test_failed" -eq 0 ]; then + exit 0 +else + echo "Some checks failed." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.7.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.7.sh new file mode 100644 index 0000000..930e44e --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.7.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + +if [ -n "${UID_MIN}" ]; then + on_disk=$(awk "/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -F *auid>=${UID_MIN}/ &&(/ -F *exit=-EACCES/||/ -F *exit=-EPERM/) &&/ -S/ &&/creat/ &&/open/ &&/truncate/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules) + + if [[ -n "$on_disk" ]]; then + exit 0 + else + exit 1 + fi +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.8.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.8.sh new file mode 100644 index 0000000..e15858c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.8.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +rules_file="/etc/audit/rules.d/50-fbPro-hardening.rules" + +if grep -qE -- '^\s*-w\s+(\/etc\/group|\/etc\/passwd|\/etc\/gshadow|\/etc\/shadow|\/etc\/security\/opasswd|\/etc\/nsswitch\.conf|\/etc\/pam\.conf|\/etc\/pam\.d)' $rules_file && + grep -qE -- '-p\s+wa' $rules_file && + grep -qE -- '(\s*key=\s*[!-~]*\s*|-\s*k\s*[!-~]*\s*)' $rules_file; then + exit 0 +else + echo "ERROR: Audit rules are NOT correctly set." + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.9.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.9.sh new file mode 100644 index 0000000..85f5de5 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.3.9.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs) + +if [ -n "$UID_MIN" ]; then + on_disk=$(awk "/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&/ -S/ &&/ -F *auid>=${UID_MIN}/ &&(/chmod/||/fchmod/||/fchmodat/ ||/chown/||/fchown/||/fchownat/||/lchown/ ||/setxattr/||/lsetxattr/||/fsetxattr/ ||/removexattr/||/lremovexattr/||/fremovexattr/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)" /etc/audit/rules.d/*.rules) + + if [[ -n "$on_disk" ]]; then + exit 0 + else + exit 1 + fi +else + echo "ERROR: Variable 'UID_MIN' is unset.\n" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.5.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.5.sh new file mode 100644 index 0000000..2ce94b1 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.5.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +l_output="" l_output2="" l_perm_mask="0137" +l_maxperm="$(printf '%o' $((0777 & ~$l_perm_mask)))" + +# Capture the output of find into a variable +l_files=$(find /etc/audit/ -type f \( -name "*.conf" -o -name '*.rules' \)) + +# Loop through each file in the list +while IFS= read -r l_fname; do + # Skip empty lines (in case of any) + [ -z "$l_fname" ] && continue + + # Get the file mode + l_mode=$(stat -Lc '%#a' "$l_fname") + + # Check if the file mode matches the permission mask + if [ $((l_mode & l_perm_mask)) -gt 0 ]; then + l_output2="$l_output2\n - file: \"$l_fname\" is mode: \"$l_mode\" (should be mode: \"$l_maxperm\" or more restrictive)" + fi +done <<<"$l_files" + +# Output the results +if [ -z "$l_output2" ]; then + exit 0 +else + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.6.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.6.sh new file mode 100644 index 0000000..2c8adb8 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.6.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +result=$(find /etc/audit/ -type f \( -name '*.conf' -o -name '*.rules' \) ! -user root) +if [ -z "$result" ]; then + exit 0 +else + echo "Files found that do not belong to the root user:" + echo "$result" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.7.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.7.sh new file mode 100644 index 0000000..1605d11 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.7.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +result=$(find /etc/audit/ -type f \( -name '*.conf' -o -name '*.rules' \) ! -group root) + +if [ -z "$result" ]; then + exit 0 +else + echo "Files found that do not belong to the root group:" + echo "$result" + exit 1 +fi diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.8.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.8.sh new file mode 100644 index 0000000..b172fc0 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.8.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +perm_mask="0022" +maxperm="$(printf '%o' $((0777 & ~$perm_mask)))" +audit_tools=("/sbin/auditctl" "/sbin/aureport" "/sbin/ausearch" "/sbin/autrace" "/sbin/auditd" "/sbin/augenrules") + +for a_tool in "${audit_tools[@]}"; do + if [ -e "$a_tool" ]; then + mode="$(stat -c '%#a' "$a_tool")" + if ((mode & perm_mask)); then + echo "Error: $a_tool has permissions that are too permissive." + exit 1 + fi + else + echo "Warning: $a_tool does not exist." + fi +done + +unset audit_tools +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.9.sh b/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.9.sh new file mode 100644 index 0000000..38475c6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/6.3.4.9.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# List of files to check +files=(/sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules) + +# Go through each file in the list and check if it exists,if a file does not exist print error +for file in "${files[@]}"; do + if [ ! -e "$file" ]; then + echo "Error: at least one file does not exist " + exit 1 + fi +done + +# Loop to check the owner of each file +for file in "${files[@]}"; do + # Check if the file is owned by root + owner=$(stat -c "%U" "$file") + if [ "$owner" != "root" ]; then + echo "Error : $file not owned by root (current owner : $owner)" + exit 1 + fi +done + +echo "All files are owned by root." +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/7.1.10.sh b/ATAPAuditor/Helpers/ShellScripts/common/7.1.10.sh new file mode 100644 index 0000000..8a895d6 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/7.1.10.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +pathOpass='/etc/security/opasswd' +pathOpassOld='/etc/security/opasswd.old' + +for p in "$pathOpass" "$pathOpassOld"; do + if [[ -e $p ]]; then + read a u g < <(stat -c '%#a %u %g' $p) + [[ $((a & 0177)) -gt 0 || $u -ne 0 || $g -ne 0 ]] && exit 1 + fi +done + +exit 0 \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/common/7.1.11.sh b/ATAPAuditor/Helpers/ShellScripts/common/7.1.11.sh new file mode 100644 index 0000000..f583a1c --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/7.1.11.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +##### NOT TESTED PROPERLY, THIS SCRIPT COULD BE CHANGED IN THE FUTURE ##### +smask="01000" + +ignored_paths=( + "/run/user/*" + "/proc/*" + "*/containerd/*" + "*/kubelet/pods/*" + "/sys/*" + "/snap/*" +) + +while read -r path; do + ignored_paths+=("$path/*") +done < <(findmnt -Dkerno fstype,target | awk '$1 ~ /^(nfs|proc|smb|vfat)$/ {print $2}') + +world_writable_files=$(find / \( ! -path "${ignored_paths[0]}" $(printf " -a ! -path %s" "${ignored_paths[@]:1}") \) \ + -type f -perm -0002 2>/dev/null) + +world_writable_dirs=$(find / -type d -perm -0002 ! -perm -$smask $(printf " -a ! -path '%s' " "${ignored_paths[@]}") 2>/dev/null) + +if [ -n "$world_writable_files" ]; then + exit 1 +fi + +if [ -n "$world_writable_dirs" ]; then + exit 1 +fi + +exit 0 diff --git a/ATAPAuditor/Helpers/ShellScripts/common/7.1.12.sh b/ATAPAuditor/Helpers/ShellScripts/common/7.1.12.sh new file mode 100644 index 0000000..9a5b8f2 --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/7.1.12.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +##### NOT TESTED PROPERLY, THIS SCRIPT COULD BE CHANGED IN THE FUTURE ##### + +ignored_paths=( + "/run/user/*" + "/proc/*" + "*/containerd/*" + "*/kubelet/pods/*" + "/sys/*" + "/snap/*" +) + +while read -r path; do + ignored_paths+=("$path/*") +done < <(findmnt -Dkerno fstype,target | awk '$1 ~ /^(nfs|proc|smb|vfat)$/ {print $2}') + +unowned=$(find / -xdev \( ! -path "${ignored_paths[@]}" \) -type f,d \( -nouser -o -nogroup \) 2>/dev/null) + +[[ -n $unowned ]] && exit 1 + +exit 0 \ No newline at end of file diff --git a/ATAPAuditor/Helpers/ShellScripts/common/7.1.9.sh b/ATAPAuditor/Helpers/ShellScripts/common/7.1.9.sh new file mode 100644 index 0000000..ceb547b --- /dev/null +++ b/ATAPAuditor/Helpers/ShellScripts/common/7.1.9.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +file="/etc/shells" + +if [[ ! -e "$file" ]]; then + exit 0 +fi + +mode=$(stat -c "%a" "$file") +uid=$(stat -c "%u" "$file") +gid=$(stat -c "%g" "$file") + +if [[ "$mode" -le 644 && "$uid" -eq 0 && "$gid" -eq 0 ]]; then + exit 0 +else + exit 1 +fi + diff --git a/ATAPAuditor/Reports/Debian 10.ps1 b/ATAPAuditor/Reports/Debian 10.ps1 new file mode 100644 index 0000000..cf7539e --- /dev/null +++ b/ATAPAuditor/Reports/Debian 10.ps1 @@ -0,0 +1,19 @@ +[Report] @{ + Title = "Debian 10 Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "Security baseline for Debian" + ) + Sections = @( + [ReportSection] @{ + Title = "General Benchmarks" + Description = "This section contains the general benchmark results" + SubSections = @( + [ReportSection] @{ + Title = 'Security Base Data' + AuditInfos = Test-AuditGroup "SBD - Linux Base Security" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Debian 11.ps1 b/ATAPAuditor/Reports/Debian 11.ps1 new file mode 100644 index 0000000..621a891 --- /dev/null +++ b/ATAPAuditor/Reports/Debian 11.ps1 @@ -0,0 +1,19 @@ +[Report] @{ + Title = "Debian 11 Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Debian 11, Version: 1.0.0, Date: 2022-09-22" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains all benchmarks from CIS" + SubSections = @( + [ReportSection] @{ + Title = 'CIS Recommendations' + AuditInfos = Test-AuditGroup "Debian Linux 11-CIS-1.0.0" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Debian 12.ps1 b/ATAPAuditor/Reports/Debian 12.ps1 new file mode 100644 index 0000000..056fc79 --- /dev/null +++ b/ATAPAuditor/Reports/Debian 12.ps1 @@ -0,0 +1,19 @@ +[Report] @{ + Title = "Debian 12 Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Debian 12, Version: 1.0.1, Date: 2024-04-15" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains the general benchmark results" + SubSections = @( + [ReportSection] @{ + Title = 'CIS Recommendations' + AuditInfos = Test-AuditGroup "Debian Linux 12-CIS-1.0.1" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Fedora 35.ps1 b/ATAPAuditor/Reports/Fedora 35.ps1 new file mode 100644 index 0000000..4b868e7 --- /dev/null +++ b/ATAPAuditor/Reports/Fedora 35.ps1 @@ -0,0 +1,19 @@ +[Report] @{ + Title = "Fedora 35 Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "Security baseline for Fedora" + ) + Sections = @( + [ReportSection] @{ + Title = "General Benchmarks" + Description = "This section contains the general benchmark results" + SubSections = @( + [ReportSection] @{ + Title = 'Security Base Data' + AuditInfos = Test-AuditGroup "SBD - Linux Base Security" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Google Chrome.ps1 b/ATAPAuditor/Reports/Google Chrome.ps1 new file mode 100644 index 0000000..dd2d506 --- /dev/null +++ b/ATAPAuditor/Reports/Google Chrome.ps1 @@ -0,0 +1,30 @@ +[Report] @{ + Title = 'Google Chrome Audit Report' + ModuleName = 'ATAPAuditor' + BasedOn = @( + "CIS Google Chrome Benchmark, Version: 2.0.0, Date: 2019-05-17" + "DISA Google Chrome Security Technical Implementation Guide, Version: V1R15, Date: 2019-01-28" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Recommendations" + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Google Chrome-CIS-2.0.0#RegistrySettings" + } + ) + } + [ReportSection] @{ + Title = "DISA Recommendations" + Description = "This section contains all DISA recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Google Chrome-DISA-V1R15#RegistrySettings" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft Edge.ps1 b/ATAPAuditor/Reports/Microsoft Edge.ps1 new file mode 100644 index 0000000..941775c --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Edge.ps1 @@ -0,0 +1,30 @@ +[Report] @{ + Title = 'Microsoft Edge Report' + ModuleName = 'ATAPAuditor' + BasedOn = @( + "CIS Microsoft Edge Benchmark, Version: 2.0.0, Date: 2023-09-21" + "Microsoft Edge v117 Security Baseline FINAL, Version: 117, Date: 2024-04-12" + ) + Sections = @( + [ReportSection] @{ + Title = 'CIS Benchmarks' + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Edge-CIS-2.0.0#RegistrySettings" + } + ) + } + [ReportSection] @{ + Title = "MS Baseline" + Description = "This section contains all Microsoft recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Edge-Microsoft-117#RegistrySettings" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft IIS10.ps1 b/ATAPAuditor/Reports/Microsoft IIS10.ps1 new file mode 100644 index 0000000..b9ac0e1 --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft IIS10.ps1 @@ -0,0 +1,2915 @@ +using namespace Microsoft.Web.Administration +using namespace Microsoft.Windows.ServerManager.Commands +Import-Module IISAdministration -Force + +$RootPath = Split-Path $MyInvocation.MyCommand.Path -Parent +$RootPath = Split-Path $RootPath -Parent +. "$RootPath\Helpers\AuditGroupFunctions.ps1" +$listOfWeakCipherSuites = getListOfWeakCipherSuites +$listOfInsecureCipherSuites = getListOfInsecureCipherSuites +#region Helper Functions +$MESSAGE_ALLGOOD = "All Good" + +function Get-IISSiteVirtualPaths { + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Site] $Site, + + [switch] $AllVirtualDirectories + ) + + process { + foreach ($App in $Site.Applications) { + Write-Output ($App.Path) + + if ($AllVirtualDirectories) { + foreach ($VirtualDirectory in $App.VirtualDirectories) { + if ($VirtualDirectory.Path -ne "/") { + $AppPath = if ($App.Path -ne "/") { + $App.Path + } + else { + "" + } + Write-Output ($AppPath + $VirtualDirectory.Path) + } + } + } + } + } +} + +function Get-IISModules { + (Get-IISConfigSection -SectionPath "system.webServer/modules").GetCollection() ` + | Get-IISConfigAttributeValue -AttributeName "Name" +} +#endregion + +#region 1 Basic Configuration +# +# This section contains basic Web server-level recommendations + +# 1.1 +function Test-IISVirtualDirPartition { + <# + .Synopsis + Ensure web content is on non-system partition + .Description + Web resources published through IIS are mapped, via Virtual Directories, to physical locations on disk. It is recommended to map all Virtual Directories to a non-system disk volume. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Site] $Site + ) + + process { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $SystemDrive = [system.environment]::getenvironmentvariable("SystemDrive") + $Path = $Site.Applications["/"].VirtualDirectories["/"].PhysicalPath + + if ($Path.StartsWith("%SystemDrive%") -or $Path.StartsWith($SystemDrive)) { + $message = "Web content is on system partition" + $audit = "False" + } + + @{ + Id = "1.1" + Task = "Ensure web content is on non-system partition" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 1.2 +function Test-IISHostHeaders { + <# + .Synopsis + Ensure 'host headers' are on all sites + .DESCRIPTION + Host headers provide the ability to host multiple websites on the same IP address and port. It is recommended that host headers be configured for all sites. Wildcard host headers are now supported. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Site] $Site + ) + + process { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + [array]$Bindings = $Site.Bindings | Where-Object { [string]::IsNullOrEmpty($_.Host) } + + if ($Bindings.Count -gt 0) { + $message = "The following bindings do no specify a host: " + ($Bindings.bindingInformation -join ", ") + $audit = "False" + } + + @{ + Id = "1.2" + Task = "Ensure 'host headers' is set" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 1.3 +function Test-IISDirectoryBrowsing { + <# + .Synopsis + Ensure 'directory browsing' is set to disabled + .Description + Directory browsing allows the contents of a directory to be displayed upon request from a web client. If directory browsing is enabled for a directory in Internet Information Services, users receive a page that lists the contents of the directory when the following two conditions are met: + + 1. No specific file is requested in the URL + 2. The Default Documents feature is disabled in IIS, or if it is enabled, IIS is unable to locate a file in the directory that matches a name specified in the IIS default document list + + It is recommended that directory browsing be disabled. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup){ + # Ensure directory browsing is installed + if ((Get-WindowsFeature Web-Dir-Browsing).InstallState -eq [InstallState]::Installed) { + $path = "system.webServer/directoryBrowse" + $section = $Configuration.GetSection($path) + + $Enabled = $section | Get-IISConfigAttributeValue -AttributeName "enabled" + + if ($Enabled -eq $true) { + $message = "Directory Browsing is enabled" + $audit = "False" + } + elseif ($null -eq $Enabled) { + $message = "Directory Browsing not explicit set to false" + $audit = "Warning" + } + } + } + else{ + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + @{ + Id = "1.3" + Task = "Ensure 'directory browsing' is set to disabled" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 1.4 +function Test-IISAppPoolIdentity { + <# + .Synopsis + Ensure 'application pool identity' is configured for all application pools + .Description + Application Pool Identities are the actual users/authorities that will run the worker process - w3wp.exe. Assigning the correct user authority will help ensure that applications can function properly, while not giving overly permissive permissions on the system. These identities can further be used in ACLs to protect system content. It is recommended that each Application Pool run under a unique identity. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [ApplicationPool] $AppPool + ) + + begin { + $AppPoolUsers = (Get-IISAppPool).ProcessModel.Username | Group-Object -NoElement + } + + process { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + if ($AppPool.ProcessModel.IdentityType -eq [ProcessModelIdentityType]::SpecificUser) { + # Get the username of the specific application + $Username = $AppPool.ProcessModel.UserName + + if (($AppPoolUsers | Where-Object Name -eq $Username).Count -gt 1) { + $message = "ApplicationPoolIdentity $Username is used for more than one ApplicationPool" + $audit = "False" + } + else { + $message = "Unique ApplicationPoolIdentity $Username is used." + $audit = "True" + } + } + elseif ($AppPool.ProcessModel.IdentityType -ne [ProcessModelIdentityType]::ApplicationPoolIdentity) { + $message = "ApplicationPoolIdentity is not set" + $audit = "False" + } + + @{ + Id = "1.4" + Task = "Ensure 'application pool identity' is configured" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 1.5 +function Test-IISUniqueSiteAppPool { + <# + .Synopsis + Ensure 'unique application pools' is set for sites + .Description + IIS introduced a new security feature called Application Pool Identities that allows Application Pools to be run under unique accounts without the need to create and manage local or domain accounts. It is recommended that all Sites run under unique, dedicated Application Pools. + #> + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $Apps = foreach ($Site in (Get-IISSite)) { + foreach ($App in $Site.Applications) { + New-Object -TypeName PSObject -Property @{ + VirtualPath = $Site.name + $App.path + ApplicationPoolName = $App.ApplicationPoolName + } + } + } + + [array]$Findings = $Apps ` + | Group-Object -Property ApplicationPoolName ` + | Where-Object -Property Count -gt 1 + + if ($Findings.Count -gt 0) { + $message = "Following sites do not have unique Application Pools: " + ($findings.Group.VirtualPath -join ", ") + $audit = "False" + } + + @{ + Id = "1.5" + Task = "Ensure 'unique application pools' is set for sites" + Status = $audit + Message = $message + } | Write-Output +} + +# 1.6 +function Test-IISAnonymouseUserIdentity { + <# + .Synopsis + Ensure 'application pool identity' is configured for anonymous user identity + .Description + To achieve isolation in IIS, application pools can be run as separate identities. IIS can be configured to automatically use the application pool identity if no anonymous user account is configured for a Web site. This can greatly reduce the number of accounts needed for Web sites and make management of the accounts easier. It is recommended the Application Pool Identity be set as the Anonymous User Identity. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup){ + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.webServer/security/authentication/anonymousAuthentication" + $section = $Configuration.GetSection($path) + + $username = $section | Get-IISConfigAttributeValue -AttributeName "userName" + + if ($username -ne "") { + $message = "Username is set to: $username" + $audit = "False" + } + } + else{ + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "1.6" + Task = "Ensure 'application pool identity' is configured for anonymous user identity" + Status = $audit + Message = $message + } | Write-Output + } +} + +#endregion + +#region 2 Configure Authentication and Authorization +# +# This section contains recommendations around the different layers of authentication in IIS. + +# 2.1 +function Test-IISGlobalAuthorization { + <# + .Synopsis + Ensure 'global authorization rule' is set to restrict access + .Description + IIS introduced URL Authorization, which allows the addition of Authorization rules to the actual URL, instead of the underlying file system resource, as a way to protect it. Authorization rules can be configured at the server, web site, folder (including Virtual Directories), or file level. The native URL Authorization module applies to all requests, whether they are .NET managed or other types of files (e.g. static files or ASP files). It is recommended that URL Authorization be configured to only grant access to the necessary security principals. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + # Ensure URL Authentication is installed + if ((Get-WindowsFeature Web-Url-Auth).InstallState -eq [InstallState]::Installed) { + $path = "system.webServer/security/authorization" + $section = $Configuration.GetSection($path) + + [array]$elements = $section.GetCollection() ` + | Where-Object { + $accessType = $_ | Get-IISConfigAttributeValue -AttributeName "accessType" + $users = $_ | Get-IISConfigAttributeValue -AttributeName "users" + $roles = $_ | Get-IISConfigAttributeValue -AttributeName "roles" + ($accessType -eq "Allow") -and ($users -eq "*" -or $roles -eq "?") + } + + if ($elements.Count -ne 0) { + $message = "Authorization rule to allow all or anonymous users is set" + $audit = "False" + } + } + else { + $message = "URL Authorization is not installed" + $audit = "Warning" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "2.1" + Task = "Ensure 'global authorization rule' is set to restrict access" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 2.2 +function Test-IISAuthenticatedPricipals { + <# + .Synopsis + Ensure access to sensitive site features is restricted to authenticated principals only + .Description + IIS supports both challenge-based and login redirection-based authentication methods. Challenge-based authentication methods, such as Integrated Windows Authentication, require a client to respond correctly to a server-initiated challenge. A login redirection-based authentication method such as Forms Authentication relies on redirection to a login page to determine the identity of the principal. Challenge-based authentication and login redirection-based authentication methods cannot be used in conjunction with one another. + + It is recommended that sites containing sensitive information, confidential data, or non-public web services be configured with a credentials-based authentication mechanism. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.web/authentication" + $section = $Configuration.GetSection($path) + + $mode = $section | Get-IISConfigAttributeValue -AttributeName "mode" + + if (($mode -ne "Windows") -and ($mode -ne "Forms")) { + $message = "Check authentication principals" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "2.2" + Task = "Ensure access to sensitive site features is restricted to authenticated principals only" + Status = $audit + Message = $message + } | Write-Output + } + +} + +# 2.3 +function Test-IISFormsAuthenticationSSL { + <# + .Synopsis + Ensure 'forms authentication' require SSL + .Description + Forms-based authentication can pass credentials across the network in clear text. It is therefore imperative that the traffic between client and server be encrypted using SSL, especially in cases where the site is publicly accessible. It is recommended that communications with any portion of a site using Forms Authentication be encrypted using SSL. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.web/authentication" + $section = $Configuration.GetSection($path) + + $mode = $section | Get-IISConfigAttributeValue -AttributeName "mode" + + if ((Get-IISModules) -contains "FormsAuthentication") { + # Ensure authentication mode is set to Forms + if ($mode -eq "Forms") { + + $requireSSL = $section ` + | Get-IISConfigElement -ChildElementName "forms" ` + | Get-IISConfigAttributeValue -AttributeName "requireSSL" + + if (-not $requireSSL) { + $message = "Forms authentication does not require SSL" + $audit = "False" + } + } + } + else { + $message = "Forms authentication is not installed" + $audit = "Warning" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "2.3" + Task = "Ensure 'forms authentication' require SSL" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 2.4 +function Test-IISFormsAuthenticationCookies { + <# + .Synopsis + Ensure 'forms authentication' is set to use cookies + .Description + Forms Authentication can be configured to maintain the site visitor's session identifier in either a URI or cookie. It is recommended that Forms Authentication be set to use cookies. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.web/authentication" + $section = $Configuration.GetSection($path) + + $mode = $section | Get-IISConfigAttributeValue -AttributeName "mode" + + if ((Get-IISModules) -contains "FormsAuthentication") { + if ($mode -eq "Forms") { + $cookieless = $section | Get-IISConfigElement -ChildElementName "forms" ` + | Get-IISConfigAttributeValue -AttributeName "cookieless" + + if ($cookieless -ne "UseCookies") { + $message = "Forms authentication is not set to use cookies" + $audit = "False" + } + } + } + else { + $message = "Forms authentication is not installed" + $audit = "Warning" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "2.4" + Task = "Ensure 'forms authentication' is set to use cookies" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 2.5 +function Test-IISFormsAuthenticationProtection { + <# + .Synopsis + Ensure 'cookie protection mode' is configured for forms authentication + .Description + The cookie protection mode defines the protection Forms Authentication cookies will be given within a configured application. + + It is recommended that cookie protection mode always encrypt and validate Forms Authentication cookies. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.web/authentication" + $section = $Configuration.GetSection($path) + + $mode = $section | Get-IISConfigAttributeValue -AttributeName "mode" + + if ((Get-IISModules) -contains "FormsAuthentication") { + if ($mode -ieq "Forms") { + $protection = $section ` + | Get-IISConfigElement -ChildElementName "forms" ` + | Get-IISConfigAttributeValue -AttributeName "protection" + + if ($protection -ne "All") { + $message = "Cookie Protection Mode is not set to ALL" + $audit = "False" + } + } + } + else { + $message = "Forms authentication is not installed" + $audit = "Warning" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "2.5" + Task = "Ensure 'cookie protection mode' is configured for forms authentication" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 2.6 +function Test-IISTLSForBasicAuth { + <# + .Synopsis + Ensure transport layer security for 'basic authentication' is configured + .Description + Basic Authentication can pass credentials across the network in clear text. It is therefore imperative that the traffic between client and server be encrypted, especially in cases where the site is publicly accessible and is recommended that TLS be configured and required for any Site or Application using Basic Authentication. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Site] $Site + ) + + process { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + if ((Get-WindowsFeature Web-Basic-Auth).InstallState -eq [InstallState]::Installed) { + [array]$httpsBindings = $Site.Bindings | Where-Object -Property Protocol -eq "https" + + $sslFlags = Get-IISConfigSection -Location $Site.Name ` + -SectionPath "system.webServer/security/access" ` + | Get-IISConfigAttributeValue -AttributeName "sslFlags" + + # split the flags into an array + $sslValues = $sslFlags.Split("{,}") + + # Ensure ssl-flag is set + if (-not ($sslValues -contains "ssl")) { + $message = "SSL is not required in configuration" + $audit = "False" + } + # Ensure site has https bindings + elseif ($httpsBindings.Count -eq 0) { + $message = "Site has no secure protocol binding" + $audit = "False" + } + } + + @{ + Id = "2.6" + Task = "Ensure transport layer security for 'basic authentication' is configured" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 2.7 +function Test-IISPasswordFormatNotClear { + <# + .Synopsis + Ensure 'passwordFormat' is not set to clear + .Description + The element of the element allows optional definitions of name and password for IIS Manager User accounts within the configuration file. Forms based authentication also uses these elements to define the users. IIS Manager Users can use the administration interface to connect to sites and applications in which they've been granted authorization. Note that the element only applies when the default provider, ConfigurationAuthenticationProvider, is configured as the authentication provider. It is recommended that passwordFormat be set to a value other than Clear, such as SHA1. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.web/authentication" + $section = $Configuration.GetSection($path) + + $passwordFormat = $section ` + | Get-IISConfigElement -ChildElementName "forms" ` + | Get-IISConfigElement -ChildElementName "credentials" ` + | Get-IISConfigAttributeValue -AttributeName "passwordFormat" + + if ($passwordFormat -eq "Clear" ) { + $message = "Credentials passwordFormat set to 'Clear'" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "2.7" + Task = "Ensure 'passwordFormat' is not set to clear" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 2.7 +function Test-IISPasswordFormatNotClearMachineLevel { + <# + .Synopsis + Ensure 'passwordFormat' is not set to clear + .Description + The element of the element allows optional definitions of name and password for IIS Manager User accounts within the configuration file. Forms based authentication also uses these elements to define the users. IIS Manager Users can use the administration interface to connect to sites and applications in which they've been granted authorization. Note that the element only applies when the default provider, ConfigurationAuthenticationProvider, is configured as the authentication provider. It is recommended that passwordFormat be set to a value other than Clear, such as SHA1. + #> + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $machineConfig = [System.Configuration.ConfigurationManager]::OpenMachineConfiguration() + $passwordFormat = $machineConfig.GetSection("system.web/authentication").forms.credentials.passwordFormat + + if ($passwordFormat -eq "Clear" ) { + $message = "Credentials passwordFormat set to 'Clear'" + $audit = "False" + } + + @{ + Id = "2.7" + Task = "Ensure 'passwordFormat' is not set to clear" + Status = $audit + Message = $message + } | Write-Output +} + +# 2.8 +function Test-IISCredentialsNotStored { + <# + .Synopsis + Ensure 'credentials' are not stored in configuration files + .Description + The element of the element allows optional definitions of name and password for IIS Manager User accounts within the configuration file. Forms based authentication also uses these elements to define the users. IIS Manager Users can use the administration interface to connect to sites and applications in which they've been granted authorization. Note that the element only applies when the default provider, ConfigurationAuthenticationProvider, is configured as the authentication provider. It is recommended to avoid storing passwords in the configuration file even in form of hash. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.web/authentication" + $section = $Configuration.GetSection($path) + + $credentials = $section ` + | Get-IISConfigElement -ChildElementName "forms" ` + | Get-IISConfigElement -ChildElementName "credentials" + + if ($credentials.IsLocallyStored) { + $message = "'credentials' is stored in configuration" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "2.8" + Task = "Ensure 'credentials' are not stored in configuration files" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 2.8 +function Test-IISCredentialsNotStoredMachineLevel { + <# + .Synopsis + Ensure 'credentials' are not stored in configuration files + .Description + The element of the element allows optional definitions of name and password for IIS Manager User accounts within the configuration file. Forms based authentication also uses these elements to define the users. IIS Manager Users can use the administration interface to connect to sites and applications in which they've been granted authorization. Note that the element only applies when the default provider, ConfigurationAuthenticationProvider, is configured as the authentication provider. It is recommended to avoid storing passwords in the configuration file even in form of hash. + #> + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $machineConfig = [System.Configuration.ConfigurationManager]::OpenMachineConfiguration() + $credentials = $machineConfig.GetSection("system.web/authentication").forms.credentials + + if ($credentials.ElementInformation.IsPresent) { + $message = "'credentials' is stored in configuration" + $audit = "False" + } + + @{ + Id = "2.8" + Task = "Ensure 'credentials' are not stored in configuration files" + Status = $audit + Message = $message + } | Write-Output +} + +#endregion + +#region 3 ASP.NET Configuration Recommendation +# +# This section contains recommendations specific to ASP.NET. + +# 3.1 +function Test-IISDeploymentMethodRetail { + <# + .Synopsis + Ensure 'deployment method retail' is set + .Description + The switch is intended for use by production IIS servers. This switch is used to help applications run with the best possible performance and least possible security information leakages by disabling the application's ability to generate trace output on a page, disabling the ability to display detailed error messages to end users, and disabling the debug switch. Often times, switches and options that are developer-focused, such as failed request tracing and debugging, are enabled during active development. It is recommended that the deployment method on any production server be set to retail. + #> + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $machineConfig = [System.Configuration.ConfigurationManager]::OpenMachineConfiguration() + $deployment = $machineConfig.GetSection("system.web/deployment") + + if (-not $deployment.retail) { + $message = "retail is not enabled in machine.config" + $audit = "False" + } + + @{ + Id = "3.1" + Task = "Ensure 'deployment method retail' is set" + Status = $audit + Message = $message + } | Write-Output +} + +# 3.2 +function Test-IISDebugOff { + <# + .Synopsis + Ensure 'debug' is turned off + .Description + Developers often enable the debug mode during active ASP.NET development so that they do not have to continually clear their browsers cache every time they make a change to a resource handler. The problem would arise from this being left "on" or set to "true". Compilation debug output is displayed to the end user, allowing malicious persons to obtain detailed information about applications. + + is recommended that debugging still be turned off. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.web/compilation" + $section = $Configuration.GetSection($path) + + $debug = $section | Get-IISConfigAttributeValue -AttributeName "debug" + + if ($debug) { + $message = "Debug is ON" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "3.2" + Task = "Ensure 'debug' is turned off" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 3.3 +function Test-IISCustomErrorsNotOff { + <# + .Synopsis + Ensure custom error messages are not off + .Description + When an ASP.NET application fails and causes an HTTP/1.x 500 Internal Server Error, or a feature configuration (such as Request Filtering) prevents a page from being displayed, an error message will be generated. Administrators can choose whether or not the application should display a friendly message to the client, detailed error message to the client, or detailed error message to localhost only. + + It is recommended that customErrors still be turned to On or RemoteOnly. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.web/customErrors" + $section = $Configuration.GetSection($path) + + $mode = $section | Get-IISConfigAttributeValue -AttributeName "mode" + + if ($mode -eq "Off") { + $message = "Custom errors are 'OFF'" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "3.3" + Task = "Ensure custom error messages are not off" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 3.4 +function Test-IISHttpErrorsHidden { + <# + .Synopsis + Ensure IIS HTTP detailed errors are hidden from displaying remotely + .Description + A Web site's error pages are often set to show detailed error information for troubleshooting purposes during testing or initial deployment. To prevent unauthorized users from viewing this privileged information, detailed error pages must not be seen by remote users. This setting can be modified in the errorMode attribute setting for a Web site's error pages. By default, the errorMode attribute is set in the Web.config file for the Web site or application and is located in the element of the section. It is recommended that custom errors be prevented from displaying remotely. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.webServer/httpErrors" + $section = $Configuration.GetSection($path) + + $errorMode = $section | Get-IISConfigAttributeValue -AttributeName "errorMode" + + if (($errorMode -ne "Custom") -and ($errorMode -ne "DetailedLocalOnly")) { + $message = "HTTP detailed errors are set to 'Detailed'" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "3.4" + Task = "Ensure IIS HTTP detailed errors are hidden from displaying remotely" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 3.5 +function Test-IISAspNetTracingDisabled { + <# + .Synopsis + Ensure ASP.NET stack tracing is not enabled + .Description + A Web site's error pages are often set to show detailed error information for troubleshooting purposes during testing or initial deployment. To prevent unauthorized users from viewing this privileged information, detailed error pages must not be seen by remote users. This setting can be modified in the errorMode attribute setting for a Web site's error pages. By default, the errorMode attribute is set in the Web.config file for the Web site or application and is located in the element of the section. It is recommended that custom errors be prevented from displaying remotely. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.web/trace" + $section = $Configuration.GetSection($path) + + $traceEnabled = $section | Get-IISConfigAttributeValue -AttributeName "enabled" + + if ($traceEnabled) { + $message = "trace is enabled" + $audit = "FALSE" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "3.5" + Task = "Ensure ASP.NET stack tracing is not enabled" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 3.5 +function Test-IISAspNetTracingDisabledMachineLevel { + <# + .Synopsis + Ensure ASP.NET stack tracing is not enabled + .Description + A Web site's error pages are often set to show detailed error information for troubleshooting purposes during testing or initial deployment. To prevent unauthorized users from viewing this privileged information, detailed error pages must not be seen by remote users. This setting can be modified in the errorMode attribute setting for a Web site's error pages. By default, the errorMode attribute is set in the Web.config file for the Web site or application and is located in the element of the section. It is recommended that custom errors be prevented from displaying remotely. + #> + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $machineConfig = [System.Configuration.ConfigurationManager]::OpenMachineConfiguration() + $trace = $machineConfig.GetSection("system.web/trace") + + if ($trace.enabled) { + $message = "trace is enabled in machine.config" + $audit = "FALSE" + } + + @{ + Id = "3.5" + Task = "Ensure ASP.NET stack tracing is not enabled" + Status = $audit + Message = $message + } | Write-Output +} + +# 3.6 +function Test-IISCookielessSessionState { + <# + .Synopsis + Ensure 'httpcookie' mode is configured for session state + .Description + A session cookie associates session information with client information for that session, which can be the duration of a user's connection to a site. The cookie is passed in a HTTP header together with all requests between the client and server. + + It is recommended that session state be configured to UseCookies. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.web/sessionState" + $section = $Configuration.GetSection($path) + + $cookieless = $section | Get-IISConfigAttributeValue -AttributeName "cookieless" + + if (($cookieless -ne "UseCookies") -and ($cookieless -ne "False")) { + $message = "sessionState set to $cookieless" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "3.6" + Task = "Ensure 'httpcookie' mode is configured for session state" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 3.7 +function Test-IISCookiesHttpOnly { + <# + .Synopsis + Ensure 'cookies' are set with HttpOnly attribute + .Description + The httpOnlyCookies attribute of the httpCookies node determines if IIS will set the HttpOnly flag on HTTP cookies it sets. The HttpOnly flag indicates to the user agent that the cookie must not be accessible by client-side script (i.e document.cookie). It is recommended that the httpOnlyCookies attribute be set to true. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.web/httpCookies" + $section = $Configuration.GetSection($path) + + $httpOnlyCookies = $section | Get-IISConfigAttributeValue -AttributeName "httpOnlyCookies" + + if (-not $httpOnlyCookies) { + $message = "httpOnlyCookies set to $httpOnlyCookies" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "3.7" + Task = "Ensure 'cookies' are set with HttpOnly attribute" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 3.8 +function Test-IISMachineKeyValidation { + <# + .Synopsis + Ensure 'MachineKey validation method - .Net 3.5' is configured + .Description + The machineKey element of the ASP.NET web.config specifies the algorithm and keys that ASP.NET will use for encryption. The Machine Key feature can be managed to specify hashing and encryption settings for application services such as view state, Forms authentication, membership and roles, and anonymous identification. + + It is recommended that AES or SHA1 methods be configured for use at the global level. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Site] $Site + ) + + process { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $siteAppPool = $Site.Applications["/"].ApplicationPoolName + $appPoolVersion = (Get-IISAppPool -Name $siteAppPool).managedRuntimeVersion + + # Ensure ApplicationPool running is .NET 3.5 (which is an extension of 2.0 so we look for 2.*) + if ($appPoolVersion -like "v2.*") { + + $validation = Get-IISConfigSection -CommitPath $Site.Name ` + -SectionPath "system.web/machineKey" ` + | Get-IISConfigAttributeValue -AttributeName "Validation" + + if ($validation -ne "SHA1") { + $message = "Validation set to $validation" + $audit = "False" + } + } + + @{ + Id = "3.8" + Task = "Ensure 'MachineKey validation method - .Net 3.5' is configured" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 3.9 +function Test-IISMachineKeyValidationV45 { + <# + .Synopsis + Ensure 'MachineKey validation method - .Net 4.5' is configured + .Description + The machineKey element of the ASP.NET web.config specifies the algorithm and keys that ASP.NET will use for encryption. The Machine Key feature can be managed to specify hashing and encryption settings for application services such as view state, Forms authentication, membership and roles, and anonymous identification. + + It is recommended that SHA-2 methods be configured for use at the global level. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Site] $Site + ) + + process { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $siteAppPool = $site.Applications["/"].ApplicationPoolName + $appPoolVersion = (Get-IISAppPool -Name $siteAppPool).managedRuntimeVersion + + # Ensure an ApplicationPool is running .NET 4.5 + if ($appPoolVersion -like "v4.*") { + $validation = Get-IISConfigSection -CommitPath $Site.name ` + -SectionPath "system.web/machineKey" ` + | Get-IISConfigAttributeValue -AttributeName "Validation" + + if (($validation -ne "HMACSHA256") -and ($validation -ne "HMACSHA512")) { + $message = "Validation set to $validation" + $audit = "False" + } + } + + @{ + Id = "3.9" + Task = "Ensure 'MachineKey validation method - .Net 4.5' is configured" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 3.10 +function Test-IISDotNetTrustLevel { + <# + .Synopsis + Ensure global .NET trust level is configured + .Description + An application's trust level determines the permissions that are granted by the ASP.NET code access security (CAS) policy. CAS defines two trust categories: full trust and partial trust. An application that has full trust permissions may access all resource types on a server and perform privileged operations, while applications that run with partial trust have varying levels of operating permissions and access to resources. + + It is recommended that the global .NET Trust Level be set to Medium or lower. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Site] $Site + ) + + process { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $siteAppPool = $site.Applications["/"].ApplicationPoolName + $appPoolVersion = (Get-IISAppPool -Name $siteAppPool).managedRuntimeVersion + + if ($appPoolVersion -like "v4.*") { + $message = "This only applies to .Net 2.0. Future versions have stopped supporting this feature." + $audit = "None" + } + else { + $level = Get-IISConfigSection -CommitPath $Site.name ` + -SectionPath "system.web/trust" ` + | Get-IISConfigAttributeValue -AttributeName "level" + + # medium trust level should be set in .NET 2.*, but not in later versions + if (($appPoolVersion -like "v2.*" -and $level -ne "medium" -or $level -ne "low" -or $level -ne "minimal") ` + -or ($appPoolVersion -notlike "v4.*" -and -not [string]::IsNullOrEmpty($appPoolVersion))) { + $message = "TrustLevel set to $level" + $audit = "False" + } + } + + @{ + Id = "3.10" + Task = "Ensure global .NET trust level is configured" + Status = $audit + Message = $message + } | Write-Output + } +} + +#endregion + +#region 4 Request Filtering and Other Restriction Modules +# +# Request Filtering is a powerful module that provides a configurable set of rules that enables administrators to allow or reject the types of requests that they determine should be allowed or rejected at the server, web site, or web application levels. + + +# 4.1 +function Test-IISMaxAllowedContentLength { + <# + .Synopsis + Ensure 'maxAllowedContentLength' is configured + .Description + The maxAllowedContentLength Request Filter is the maximum size of the http request, measured in bytes, which can be sent from a client to the server. Configuring this value enables the total request size to be restricted to a configured value. It is recommended that the overall size of requests be restricted to a maximum value appropriate for the server, site, or application. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + # Ensure request filering is installed + if ((Get-WindowsFeature Web-Filtering).InstallState -eq [InstallState]::Installed) { + $path = "system.webServer/security/requestFiltering" + $section = $Configuration.GetSection($path) + + $maxContentLength = $section ` + | Get-IISConfigElement -ChildElementName "requestLimits" ` + | Get-IISConfigAttributeValue -AttributeName "maxAllowedContentLength" + + if ($maxContentLength -ge 0) { + $message += "`n maxContentLength: $maxContentLength" + } + else { + $message = "maxContentLength not configured" + $audit = "False" + } + } + else { + $message = "Request Filering is not installed" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "4.1" + Task = "Ensure 'maxAllowedContentLength' is configured" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 4.2 +function Test-IISMaxURLRequestFilter { + <# + .Synopsis + Ensure 'maxURL request filter' is configured + .Description + The maxURL attribute of the property is the maximum length (in Bytes) in which a requested URL can be (excluding query string) in order for IIS to accept. Configuring this Request Filter enables administrators to restrict the length of the requests that the server will accept. It is recommended that a limit be put on the length of URL. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + # Ensure request filering is installed + if ((Get-WindowsFeature Web-Filtering).InstallState -eq [InstallState]::Installed) { + $path = "system.webServer/security/requestFiltering" + $section = $Configuration.GetSection($path) + + $maxURLRequestFilter = $section ` + | Get-IISConfigElement -ChildElementName "requestLimits" ` + | Get-IISConfigAttributeValue -AttributeName "maxURL" + + if ($maxURLRequestFilter -ge 1) { + $message += "`n maxURLRequestFilter: $maxURLRequestFilter" + } + else { + $message = "maxURLRequestFilter not configured" + $audit = "False" + } + } + else { + $message = "Request Filering is not installed" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + + @{ + Id = "4.2" + Task = "Ensure 'maxURL request filter' is configured" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 4.3 +function Test-IISMaxQueryStringRequestFilter { + <# + .Synopsis + Ensure 'MaxQueryString request filter' is configured + .Description + The MaxQueryString Request Filter describes the upper limit on the length of the query string that the configured IIS server will allow for websites or applications. It is recommended that values always be established to limit the amount of data will can be accepted in the query string. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + # Ensure request filering is installed + if ((Get-WindowsFeature Web-Filtering).InstallState -eq [InstallState]::Installed) { + $path = "system.webServer/security/requestFiltering" + $section = $Configuration.GetSection($path) + + $maxQueryStringRequestFilter = $section ` + | Get-IISConfigElement -ChildElementName "requestLimits" ` + | Get-IISConfigAttributeValue -AttributeName "maxQueryString" + + if ($maxQueryStringRequestFilter -ge 1) { + $message += "`n maxQueryStringRequestFilter: $maxQueryStringRequestFilter" + } + else { + $message = "maxQueryStringRequestFilter not configured" + $audit = "False" + } + } + else { + $message = "Request Filering is not installed" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "4.3" + Task = "Ensure 'MaxQueryString request filter' is configured" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 4.4 +function Test-IISNonASCIICharURLForbidden { + <# + .Synopsis + Ensure non-ASCII characters in URLs are not allowed + .Description + This feature is used to allow or reject all requests to IIS that contain non-ASCII characters. When using this feature, Request Filtering will deny the request if high-bit characters are present in the URL. The UrlScan equivalent is AllowHighBitCharacters. It is recommended that requests containing non-ASCII characters be rejected, where possible. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + # Ensure request filering is installed + if ((Get-WindowsFeature Web-Filtering).InstallState -eq [InstallState]::Installed) { + $path = "system.webServer/security/requestFiltering" + $section = $Configuration.GetSection($path) + + $allowHighBitCharacters = $section ` + | Get-IISConfigAttributeValue -AttributeName "allowHighBitCharacters" + + if ($allowHighBitCharacters) { + $message = "non-ASCII characters in URLs are allowed" + $audit = "False" + } + } + else { + $message = "Request Filering is not installed" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "4.4" + Task = "Ensure non-ASCII characters in URLs are not allowed" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 4.5 +function Test-IISRejectDoubleEncodedRequests { + <# + .Synopsis + Ensure Double-Encoded requests will be rejected + .Description + This Request Filter feature prevents attacks that rely on double-encoded requests and applies if an attacker submits a double-encoded request to IIS. When the double-encoded requests filter is enabled, IIS will go through a two iteration process of normalizing the request. If the first normalization differs from the second, the request is rejected and the error code is logged as a 404.11. The double-encoded requests filter was the VerifyNormalization option in UrlScan. It is recommended that double-encoded requests be rejected. + #> + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + # Ensure request filering is installed + if ((Get-WindowsFeature Web-Filtering).InstallState -eq [InstallState]::Installed) { + $path = "system.webServer/security/requestFiltering" + $section = $Configuration.GetSection($path) + + $allowDoubleEscaping = $section` + | Get-IISConfigAttributeValue -AttributeName "allowDoubleEscaping" + + if ($allowDoubleEscaping) { + $message = "Rejecting Double-Encoded requests not set" + $audit = "False" + } + } + else { + $message = "Request Filering is not installed" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "4.5" + Task = "Ensure Double-Encoded requests will be rejected" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 4.6 +function Test-IISHTTPTraceMethodeDisabled { + <# + .Synopsis + Ensure 'HTTP Trace Method' is disabled + .Description + The HTTP TRACE method returns the contents of client HTTP requests in the entity-body of the TRACE response. Attackers could leverage this behavior to access sensitive information, such as authentication data or cookies, contained in the HTTP headers of the request. One such way to mitigate this is by using the element of the collection. The element replaces the [AllowVerbs] and [DenyVerbs] features in UrlScan. It is recommended the HTTP TRACE method be denied. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = "HTTP Trace Method is not filtered" + $audit = "False" + + # Ensure request filering is installed + if ((Get-WindowsFeature Web-Filtering).InstallState -eq [InstallState]::Installed) { + $path = "system.webServer/security/requestFiltering" + $section = $Configuration.GetSection($path) + + [array]$httpTraceMethod = $section.GetCollection("verbs") ` + | Where-Object { + $trace = $_ | Get-IISConfigAttributeValue -AttributeName "verb" + $allowed = $_ | Get-IISConfigAttributeValue -AttributeName "allowed" + ($trace -eq "trace") -and (-not $allowed) + } + + if ($httpTraceMethod.Count -eq 1) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + } + else { + $message = "Request Filering is not installed" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "4.6" + Task = "Ensure 'HTTP Trace Method' is disabled" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 4.7 +function Test-IISBlockUnlistedFileExtensions { + <# + .Synopsis + Ensure Unlisted File Extensions are not allowed + .Description + The FileExtensions Request Filter allows administrators to define specific extensions their web server(s) will allow and disallow. The property allowUnlisted will cover all other file extensions not explicitly allowed or denied. Often times, extensions such as .config, .bat, .exe, to name a few, should never be served. The AllowExtensions and DenyExtensions options are the UrlScan equivalents. It is recommended that all extensions be unallowed at the most global level possible, with only those necessary being allowed. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + if ((Get-WindowsFeature Web-Filtering).InstallState -eq [InstallState]::Installed) { + $path = "system.webServer/security/requestFiltering" + + $section = $Configuration.GetSection($path) + + $allowUnlisted = $section ` + | Get-IISConfigElement -ChildElementName "fileExtensions" ` + | Get-IISConfigAttributeValue -AttributeName "allowUnlisted" + + + if ($allowUnlisted) { + $message = "Unlisted file extensions allowed" + $audit = "False" + } + } + else { + $message = "Request Filering is not installed" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "4.7" + Task = "Ensure Unlisted File Extensions are not allowed" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 4.8 +function Test-IISHandlerDenyWrite { + <# + .Synopsis + Ensure Handler is not granted Write and Script/Execute + .Description + Handler mappings can be configured to give permissions to Read, Write, Script, or Execute depending on what the use is for - reading static content, uploading files, executing scripts, etc. It is recommended to grant a handler either Execute/``Script or Write permissions, but not both. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "system.webServer/handlers" + $section = $Configuration.GetSection($path) + $accessPolicy = ($section | Get-IISConfigAttributeValue -AttributeName "accessPolicy").Split(",") + + if ((($accessPolicy -contains "Script") -or ($accessPolicy -contains "Execute")) ` + -and ($accessPolicy -contains "Write")) { + $message = "Handler is granted write and script/execute" + $audit = "False" + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "4.8" + Task = "Ensure Handler is not granted Write and Script/Execute" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 4.9 +function Test-IISIsapisNotAllowed { + <# + .Synopsis + Ensure 'notListedIsapisAllowed' is set to false + .Description + The notListedIsapisAllowed attribute is a server-level setting that is located in the ApplicationHost.config file in the element of the section under . This element ensures that malicious users cannot copy unauthorized ISAPI binaries to the Web server and then run them. It is recommended that notListedIsapisAllowed be set to false. + #> + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + try { + $isapiCgiRestriction = Get-IISConfigSection ` + -SectionPath "system.webServer/security/isapiCgiRestriction" ` + | Get-IISConfigAttributeValue -AttributeName "notListedIsapisAllowed" + + # Verify that the notListedIsapisAllowed attribute in the element is set to false + if ($isapiCgiRestriction) { + $message = "IsapiCgiRestriction 'notListedIsapisAllowed' not set to false" + $audit = "False" + } + } + catch { + $message = "Cannot get setting 'notListedIsapisAllowed' for IsapiCgiRestriction" + $audit = "False" + } + + @{ + Id = "4.9" + Task = "Ensure 'notListedIsapisAllowed' is set to false" + Status = $audit + Message = $message + } | Write-Output +} + +# 4.10 +function Test-IISCgisNotAllowed { + <# + .Synopsis + Ensure 'notListedCgisAllowed' is set to false + .Description + The notListedCgisAllowed attribute is a server-level setting that is located in the ApplicationHost.config file in the element of the section under . This element ensures that malicious users cannot copy unauthorized CGI binaries to the Web server and then run them. It is recommended that notListedCgisAllowed be set to false. + #> + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + try { + $isapiCgiRestriction = Get-IISConfigSection ` + -SectionPath "system.webServer/security/isapiCgiRestriction" ` + | Get-IISConfigAttributeValue -AttributeName "notListedCgisAllowed" + + # Verify that the notListedCgisAllowed attribute in the element is set to false + if ($isapiCgiRestriction) { + $message = "IsapiCgiRestriction 'notListedCgisAllowed' not set to false" + $audit = "False" + } + } + catch { + $message = "Cannot get setting 'notListedCgisAllowed' for IsapiCgiRestriction" + $audit = "False" + } + + @{ + Id = "4.10" + Task = "Ensure 'notListedCgisAllowed' is set to false" + Status = $audit + Message = $message + } | Write-Output +} + +# 4.11 +function Test-IISDynamicIPRestrictionEnabled { + <# + .Synopsis + Ensure 'Dynamic IP Address Restrictions' is enabled + .Description + IIS Dynamic IP Address Restrictions capability can be used to thwart DDos attacks. This is complimentary to the IP Addresses and Domain names Restrictions lists that can be manually maintained within IIS. In contrast, Dynamic IP address filtering allows administrators to configure the server to block access for IPs that exceed the specified request threshold. The default action Deny action for restrictions is to return a Forbidden response to the client. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Site] $Site + ) + + process { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + # Ensure the windows feature is installed + if ((Get-WindowsFeature Web-Ip-Security).InstallState -ne [InstallState]::Installed) { + $message = "`"IP and Domain Restrictions`" must be installed to enabled `"Dynamic IP Address Restrictions`"" + $audit = "False" + } + else { + $dynamicIpSecurity = Get-IISConfigSection -Location $Site.Name ` + -SectionPath "system.webServer/security/dynamicIpSecurity" + + $denyByConcurrentRequests = $dynamicIpSecurity ` + | Get-IISConfigElement -ChildElementName "denyByConcurrentRequests" ` + | Get-IISConfigAttributeValue -AttributeName "enabled" + + $denyByRequestRate = $dynamicIpSecurity ` + | Get-IISConfigElement -ChildElementName "denyByRequestRate" ` + | Get-IISConfigAttributeValue -AttributeName "enabled" + + if ($denyByConcurrentRequests -and -not $denyByRequestRate) { + $message = "Deny IP Address based on the number of requests over a period of time disabled" + $audit = "False" + } + elseif (-not $denyByConcurrentRequests -and $denyByRequestRate) { + $message = "Deny IP Address based on the number of concurrent requests disabled" + $audit = "False" + } + elseif (-not $denyByConcurrentRequests -and -not $denyByRequestRate) { + $message = "Dynamic IP Restriction disabled" + $audit = "False" + } + } + + @{ + Id = "4.11" + Task = "Ensure 'Dynamic IP Address Restrictions' is enabled" + Status = $audit + Message = $message + } | Write-Output + } +} + +#endregion + +#region 5 IIS Logging Recommendations +# +# This section contains recommendations regarding IIS logging that have not been covered in the Basic Configurations section. + +# 5.1 +function Test-IISLogFileLocation { + <# + .Synopsis + Ensure Default IIS web log location is moved + .Description + IIS will log relatively detailed information on every request. These logs are usually the first item looked at in a security response, and can be the most valuable. Malicious users are aware of this, and will often try to remove evidence of their activities. It is therefore recommended that the default location for IIS log files be changed to a restricted, non-system drive. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Site] $Site + ) + + process { + $logFileLocation = ($Site.logFile.Directory).replace("%SystemDrive%", $env:SystemDrive) + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + if ($logFileLocation.StartsWith($env:SystemDrive)) { + $message = "Logfile location is on system drive: $logFileLocation" + $audit = "False" + } + + @{ + Id = "5.1" + Task = "Ensure Default IIS web log location is moved" + Status = $audit + Message = $message + } | Write-Output + } +} + +# 5.2 +function Test-IISAdvancedLoggingEnabled { + <# + .Synopsis + Ensure Advanced IIS logging is enabled + .Description + IIS Advanced Logging is a module which provides flexibility in logging requests and client data. It provides controls that allow businesses to specify what fields are important, easily add additional fields, and provide policies pertaining to log file rollover and Request Filtering. HTTP request/response headers, server variables, and client-side fields can be easily logged with minor configuration in the IIS management console. It is recommended that Advanced Logging be enabled, and the fields which could be of value to the type of business or application in the event of a security incident, be identified and logged. + #> + + # check site defaults + + @{ + Id = "5.2" + Task = "Ensure Advanced IIS logging is enabled" + Status = "None" + Message = "Advanced Logging is not available for IIS 10. See enhanced logging instead." + } | Write-Output +} + +# 5.3 +function Test-IISETWLoggingEnabled { + <# + .Synopsis + Ensure 'ETW Logging' is enabled + .Description + IIS introduces a new logging method. Administrators can now send logging information to Event Tracing for Windows (ETW) + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Site] $Site + ) + + process { + $message = $MESSAGE_ALLGOOD + $audit = "True" + + if (-not ($Site.logFile.logTargetW3C -like "*ETW*")) { + $message = "ETW Logging disabled" + $audit = "False" + } + + @{ + Id = "5.3" + Task = "Ensure 'ETW Logging' is enabled" + Status = $audit + Message = $message + } | Write-Output + } +} + +#endregion + +#region 6 FTP Requests +# +# This section contains a crucial configuration setting for running file transfer protocol (FTP). + +# 6.1 +function Test-IISFtpRequestsEncrypted { + <# + .Synopsis + Ensure FTP requests are encrypted + .Description + The new FTP Publishing Service for IIS supports adding an SSL certificate to an FTP site. Using an SSL certificate with an FTP site is also known as FTP-S or FTP over Secure Socket Layers (SSL). FTP-S is an RFC standard (RFC 4217) where an SSL certificate is added to an FTP site and thereby making it possible to perform secure file transfers. + #> + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + if ((Get-WindowsFeature Web-Ftp-Server).InstallState -eq [InstallState]::Installed) { + try { + $sslConfigElement = Get-IISConfigSection ` + -SectionPath "system.applicationHost/sites" ` + | Get-IISConfigElement -ChildElementName "siteDefaults" ` + | Get-IISConfigElement -ChildElementName "ftpServer" ` + | Get-IISConfigElement -ChildElementName "security" ` + | Get-IISConfigElement -ChildElementName "ssl" + + $controlChannelPolicy = $sslConfigElement ` + | Get-IISConfigAttributeValue -AttributeName "controlChannelPolicy" + + $dataChannelPolicy = $sslConfigElement ` + | Get-IISConfigAttributeValue -AttributeName "dataChannelPolicy" + + if (($controlChannelPolicy -ne "SslRequire") -or ($dataChannelPolicy -ne "SslRequire")) { + $message = "Found following settings: `n controlChannelPolicy: $controlChannelPolicy `n dataChannelPolicy: $dataChannelPolicy" + $audit = "False" + } + } + catch { + $message = "Cannot get FTP security setting" + $audit = "False" + } + } + else { + $message = "Skipped this benchmark - right now Web-Ftp-Server is not installed" + $audit = "None" + } + + @{ + Id = "6.1" + Task = "Ensure FTP requests are encrypted" + Status = $audit + Message = $message + } | Write-Output +} + +# 6.2 +function Test-IISFtpLogonAttemptRestriction { + <# + .Synopsis + Ensure FTP Logon attempt restrictions is enabled + .Description + IIS introduced a built-in network security feature to automatically block brute force FTP attacks. This can be used to mitigate a malicious client from attempting a brute-force attack on a discovered account, such as the local administrator account. + #> + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + if ((Get-WindowsFeature Web-Ftp-Server).InstallState -eq [InstallState]::Installed) { + try { + $denyByFailure = Get-IISConfigSection ` + -SectionPath "system.ftpServer/security/authentication" ` + | Get-IISConfigElement -ChildElementName "denyByFailure" + + $enabled = $denyByFailure ` + | Get-IISConfigAttributeValue -AttributeName "enabled" + $maxFailure = $denyByFailure ` + | Get-IISConfigAttributeValue -AttributeName "maxFailure" + $entryExpiration = $denyByFailure ` + | Get-IISConfigAttributeValue -AttributeName "entryExpiration" + $loggingOnlyMode = $denyByFailure ` + | Get-IISConfigAttributeValue -AttributeName "loggingOnlyMode" + + if (($enabled) -and ($maxFailure -gt 0) -and ($entryExpiration -gt 0) -and (-not $loggingOnlyMode)) { + # All good + } + elseif (-not $enabled ) { + $message = "Feature disabled" + $audit = "False" + } + else { + $message = "Feature enabled, but check settings. Found: `n maxFailure: " ` + + $maxFailure + "`n entryExpiration: " ` + + $entryExpiration + "`n Only logging mode: " ` + + $loggingOnlyMode + $audit = "False" + } + } + catch { + $audit = "False" + $message = "Cannot get FTP Logon attempt settings" + } + } + else { + $message = "Skipped this benchmark - right now Web-Ftp-Server is not installed" + $audit = "None" + } + + @{ + Id = "6.2" + Task = "Ensure FTP Logon attempt restrictions is enabled" + Status = $audit + Message = $message + } | Write-Output +} + +#endregion + +#region 7 Transport Encryption +# +# This section contains recommendations for configuring IIS protocols and cipher suites. + +# 7.1 +function Test-IISHSTSHeaderSet { + <# + .Synopsis + Ensure HSTS Header is set + .Description + HTTP Strict Transport Security (HSTS) allows a site to inform the user agent to communicate with the site only over HTTPS. This header takes two parameters: max-age, "specifies the number of seconds, after the reception of the STS header field, during which the user agent regards the host (from whom the message was received) as a Known HSTS Host [speaks only HTTPS]"; and includeSubDomains. includeSubDomains is an optional directive that defines how this policy is applied to subdomains. If includeSubDomains is included in the header, it provides the following definition: this HSTS Policy also applies to any hosts whose domain names are subdomains of the Known HSTS Host's domain name. + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] $Configuration + ) + + process { + #Ensure $Configuration is not empty + if ($Configuration.RootSectionGroup) { + $message = "HSTS Header not set" + $audit = "False" + + $path = "system.webServer/httpProtocol" + $section = $Configuration.GetSection($path) + + [array]$customHeaders = $section.GetCollection("customHeaders") ` + | Where-Object { + $name = $_ | Get-IISConfigAttributeValue -AttributeName "name" + $name -eq "Strict-Transport-Security" + } + + if ($customHeaders.Count -eq 1) { + $value = $customHeaders[0] | Get-IISConfigAttributeValue -AttributeName "value" + $pattern = [regex]::new("max-age=(?[0-9]*)") + $match = $pattern.Match($value) + + if ($match.Success) { + [int]$maxAge = $match.Groups["maxage"].Value + if ($maxAge -eq 0) { + $message = "Max-age should be at least be higher than 0. It is recommended to set max-age to at least 480 seconds. Max-age is set at $maxAge" + $audit = "False" + } + elseif ($maxAge -lt 480) { + $message = "It is recommended to set max-age to at least 480 seconds. Max-age is set at $maxAge" + $audit = "Warning" + } + else { + $message = $MESSAGE_ALLGOOD + ". Max-age is set at $maxAge" + $audit = "True" + } + } + } + } + else { + $message = "Cannot read configuration file, the reference to the directory may not be correct or present" + $audit = "Warning" + } + + @{ + Id = "7.1" + Task = "Ensure HSTS Header is set" + Status = $audit + Message = $message + } | Write-Output + } + +} + +# 7.2 +function Test-IISSSL2Disabled { + <# + .Synopsis + Ensure SSLv2 is disabled + .Description + This protocol is not considered cryptographically secure. Disabling it is recommended. This protocol is disabled by default if the registry key is not present. A reboot is required for these changes to be reflected. + #> + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0" + + # SSL is disabled by default + # if $path exists, $path/server should also exist + if ((Test-Path $path) -and (Test-Path "$path\Server")) { + # Ensure the following key exists + $Key = Get-Item "$path\Server" + if ($null -ne $Key.GetValue("Enabled", $null)) { + $value = Get-ItemProperty "$path\Server" | Select-Object -ExpandProperty "Enabled" + # Ensure it is set to 0 + if ($value -ne 0) { + $message = "SSL 2.0 is enabled" + $audit = "False" + } + } + } + + @{ + Id = "7.2" + Task = "Ensure SSLv2 is disabled" + Status = $audit + Message = $message + } | Write-Output +} + +# 7.3 +function Test-IISSSL3Disabled { + <# + .Synopsis + Ensure SSLv3 is disabled + .Description + This protocol is not considered cryptographically secure. Disabling it is recommended. + #> + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0" + + # SSL is disabled by default + # if $path exists, $path/server should also exist + if ((Test-Path $path) -and (Test-Path "$path\Server")) { + # Ensure the following key exists + $Key = Get-Item "$path\Server" + if ($null -ne $Key.GetValue("Enabled", $null)) { + $value = Get-ItemProperty "$path\Server" | Select-Object -ExpandProperty "Enabled" + # Ensure it is set to 0 + if ($value -ne 0) { + $message = "SSL 3.0 is enabled" + $audit = "False" + } + } + } + + @{ + Id = "7.3" + Task = "Ensure SSLv3 is disabled" + Status = $audit + Message = $message + } | Write-Output +} + +# 7.4 +function Test-IISTLSDisabled { + <# + .Synopsis + Ensure TLS 1.0 is disabled + .Description + The PCI Data Security Standard 3.1 recommends disabling "early TLS" along with SSL: + + SSL and early TLS are not considered strong cryptography and cannot be used as a security control after June 30, 2016. + #> + + $message = "TLS 1.0 is enabled" + $audit = "False" + + $path = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" + + # TLS 1.0 is enabled by default + if (Test-Path $path) { + # Ensure the following key exists + $Key = Get-Item $path + if ($null -ne $Key.GetValue("Enabled", $null)) { + $value = Get-ItemProperty $path | Select-Object -ExpandProperty "Enabled" + # Ensure it is set to 0 + if ($value -eq 0) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + } + elseif ($null -ne $Key.GetValue("DisabledByDefault", $null)) { + $value = Get-ItemProperty $path | Select-Object -ExpandProperty "DisabledByDefault" + # Ensure it is set to 1 + if ($value -eq 1) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + } + } + + @{ + Id = "7.4" + Task = "Ensure TLS 1.0 is disabled" + Status = $audit + Message = $message + } | Write-Output +} + +# 7.5 +function Test-IISTLS1_1Disabled { + <# + .Synopsis + Ensure TLS 1.1 is disabled + .Description + TLS 1.1 is required for backward compatibility. Ensure you fully test your application to ensure that backwards compatibility is not needed. If it is, build in exceptions as necessary for backwards compatibility. + #> + + $message = "TLS 1.1 is enabled" + $audit = "False" + + + $path = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" + + # TLS is enabled by default + if (Test-Path $path) { + # Ensure the following key exists + $Key = Get-Item $path + if ($null -ne $Key.GetValue("Enabled", $null)) { + $value = Get-ItemProperty $path | Select-Object -ExpandProperty "Enabled" + # Ensure it is set to 0 + if ($value -eq 0) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + } + elseif ($null -ne $Key.GetValue("DisabledByDefault", $null)) { + $value = Get-ItemProperty $path | Select-Object -ExpandProperty "DisabledByDefault" + # Ensure it is set to 1 + if ($value -eq 1) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + } + } + + @{ + Id = "7.5" + Task = "Ensure TLS 1.1 is disabled" + Status = $audit + Message = $message + } | Write-Output +} + +# 7.6 +function Test-IISTLS1_2Enabled { + <# + .Synopsis + Ensure TLS 1.2 is enabled + .Description + TLS 1.2 is the most recent and mature protocol for protecting the confidentiality and integrity of HTTP traffic. Enabling TLS 1.2 is recommended. This protocol is enabled by default if the registry key is not present. As with any registry changes, a reboot is required for changes to take effect. + #> + + $message = $MESSAGE_ALLGOOD + $audit = "True" + + $path = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2" + + # if $path exists, $path/server should also exist + # TLS 1.2 is enabled by default + if ((Test-Path $path) -and (Test-Path "$path\Server")) { + # Ensure the following key exists + $Key = Get-Item "$path\Server" + if ($null -ne $Key.GetValue("Enabled", $null)) { + $value = Get-ItemProperty "$path\Server" | Select-Object -ExpandProperty "Enabled" + if ($value -ne 1) { + $message = "TLS 1.2 is disabled" + $audit = "False" + } + } + else { + $message = "TLS 1.2 is disabled" + $audit = "False" + } + + if ($null -ne $Key.GetValue("DisabledByDefault", $null)) { + # Get-ItemProperty returns a [UInt32] + $value = Get-ItemProperty "$path\Server" | Select-Object -ExpandProperty "DisabledByDefault" + if ($value -ne 0) { + $message = "TLS 1.2 is disabled by default" + $audit = "False" + } + } + else { + $message = "TLS 1.2 is disabled" + $audit = "False" + } + } + + @{ + Id = "7.6" + Task = "Ensure TLS 1.2 is enabled" + Status = $audit + Message = $message + } | Write-Output +} + +# 7.7 +function Test-IISNullCipherDisabled { + <# + .Synopsis + Ensure NULL Cipher Suites is disabled + .Description + The NULL cipher does not provide data confidentiality or integrity. It is recommended that the NULL cipher be disabled. + #> + + $message = "NULL cipher is enabled" + $audit = "False" + + $path = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\NULL\" + + if (Test-Path $path) { + $Key = Get-Item $path + if ($null -ne $Key.GetValue("Enabled", $null)) { + $value = Get-ItemProperty $path | Select-Object -ExpandProperty "Enabled" + if ($value -eq 0) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + } + } + else { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + + @{ + Id = "7.7" + Task = "Ensure NULL Cipher Suites is disabled" + Status = $audit + Message = $message + } | Write-Output +} + +# 7.8 +function Test-IISDESCipherDisabled { + <# + .Synopsis + Ensure DES Cipher Suites is disabled + .Description + DES is a weak symmetric-key cipher. It is recommended that it be disabled. + #> + + $message = "DES cipher is enabled" + $audit = "False" + + $path = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\DES 56/56\" + + if (Test-Path $path) { + $Key = Get-Item $path + if ($null -ne $Key.GetValue("Enabled", $null)) { + $value = Get-ItemProperty $path | Select-Object -ExpandProperty "Enabled" + if ($value -eq 0) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + } + } + else { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + + @{ + Id = "7.8" + Task = "Ensure DES Cipher Suites is disabled" + Status = $audit + Message = $message + } | Write-Output +} + +# 7.9 +function Test-IISRC4CipherDisabled { + <# + .Synopsis + Ensure RC4 Cipher Suites is disabled + .Description + RC4 is a stream cipher that has known practical attacks. It is recommended that RC4 be disabled. The only RC4 cipher enabled by default on Server 2012 and 2012 R2 is RC4 128/128. + #> + + $rc4Ciphers = @("RC4 40/128", "RC4 56/128", "RC4 64/128", "RC4 128/128") + + $index = 1 + foreach ($rc4Cipher in $rc4Ciphers) { + $message = "$rc4Cipher cipher is enabled" + $audit = "False" + + $path = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\$rc4Cipher\" + + if (Test-Path $path) { + $Key = Get-Item $path + if ($null -ne $Key.GetValue("Enabled", $null)) { + $value = Get-ItemProperty $path | Select-Object -ExpandProperty "Enabled" + if ($value -eq 0) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + } + } + else { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + + @{ + Id = "7.9.$index" + Task = "Ensure RC4 Cipher Suites is disabled" + Status = $audit + Message = $message + } | Write-Output + + $index++ + } +} + +# 7.10 +function Test-IISAES128Disabled { + <# + .Synopsis + Ensure AES 128/128 Cipher Suite is configured + .Description + Enabling AES 128/128 may be required for client compatibility. Enable or disable this cipher suite accordingly. + #> + + $message = "AES 128/128 Cipher Suite is still enabled" + $audit = "False" + + try { + # Get-ItemProperty returns a [UInt32] + $enabled = Get-ItemProperty "HKLM:\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\AES 128/128\" ` + -ErrorAction Stop ` + | Select-Object ` + -ExpandProperty Enabled + + if ($enabled -eq 0) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + + } + catch { + # do anything here + } + + # If the key/value is not present,Triple AES 128/128 Cipher is disabled + + @{ + Id = "7.10" + Task = "Ensure AES 128/128 Cipher Suite is disabled" + Status = $audit + Message = $message + } | Write-Output +} + +# 7.11 +function Test-IISAES256Enabled { + <# + .Synopsis + Ensure AES 256/256 Cipher Suite is enabled + .Description + AES 256/256 is the most recent and mature cipher suite for protecting the confidentiality and integrity of HTTP traffic. Enabling AES 256/256 is recommended. This is enabled by default on Server 2012 and 2012 R2. + #> + + $message = "AES 256/256 Cipher is disabled" + $audit = "False" + + $path = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\AES 256/256\" + + if (Test-Path $path) { + $Key = Get-Item $path + if ($null -ne $Key.GetValue("Enabled", $null)) { + $value = Get-ItemProperty $path | Select-Object -ExpandProperty "Enabled" + if ($value -eq 1) { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + } + } + else { + $message = $MESSAGE_ALLGOOD + $audit = "True" + } + + @{ + Id = "7.11" + Task = "Ensure AES 256/256 Cipher Suite is enabled" + Status = $audit + Message = $message + } | Write-Output +} + +# 7.12 +function Test-IISTLSCipherOrder { + <# + .Synopsis + Ensure TLS Cipher Suite ordering is configured + .Description + Cipher suites are a named combination of authentication, encryption, message authentication code, and key exchange algorithms used for the security settings of a network connection using TLS protocol. Clients send a cipher list and a list of ciphers that it supports in order of preference to a server. The server then replies with the cipher suite that it selects from the client cipher suite list. + #> + $task = "Ensure TLS Cipher Suite ordering is correctly configured" + $id = "7.12" + try { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002" ` + -Name "Functions" + $reference = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" + $res = $regValue.Functions.GetType().Name + + #check if correct type + $typeTable = @{ + "String" = "String Value" + "Byte" = "Byte Value" + "Int32" = "DWORD (32-bit) Value" + "Int64" = "QWORD (64-bit) Value" + "String[]" = "Multi-String Value" + } + + $currentType = $typeTable[$res] + if ($res -ne [String]) { + @{ + Id = $id + Task = $task + Status = "False" + Message = "Wrong Registry type! Registry type is '$currentType'. Expected: 'String Value'" + } | Write-Output + } + + #check if insecure or weak cipher is inside value + $regValues = $regValue.Split(',') + $regValues = $regValues -replace ' ', '' + $weakRulesFound = @() + $insecureRulesFound = @() + foreach($element in $regValues){ + if($listOfWeakCipherSuites.Contains($element)){ + $weakRulesFound += $element + } + if($listOfInsecureCipherSuites.Contains($element)){ + $insecureRulesFound += $element + } + } + #Default status + $status = "Error" + + #Output + $verbInsecure = "rules have" + $verbWeak = "rules have" + if($insecureRulesFound.Count -eq 1){$verbInsecure = "rule has"} + if($weakRulesFound.Count -eq 1){$verbWeak = "rule has"} + $insecureMessage = "$($insecureRulesFound.Count) insecure $($verbInsecure) been found! List of insecure rules:
" + $weakMessage = "$($weakRulesFound.Count) weak $($verbWeak) been found! List of weak rules:
" + + #Preparing message + foreach($member in $weakRulesFound){ + $status = "Warning" + $weakMessage += "$($member)
" + } + foreach($member in $insecureRulesFound){ + $status = "False" + $insecureMessage += "$($member)
" + } + #Combine or shorten message + if($insecureRulesFound.Count -gt 0 -or $weakRulesFound.Count -gt 0){ + $message = "" + if($weakRulesFound.Count -eq 0){ $weakMessage = "" } + if($insecureRulesFound.Count -eq 0){ $insecureMessage = "" } + + $message = $insecureMessage + $weakMessage + @{ + Id = $id + Task = $task + Status = $status + Message = $message + } | Write-Output + } + + if ($regValue -ne $reference) { + @{ + Id = $id + Task = $task + Status = "True" + Message = "Compliant" + } | Write-Output + } + } + catch { + $regValue = Get-ItemProperty -ErrorAction Stop ` + -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002" ` + -Name "Functions" + $reference = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" + $res = $regValue.Functions.GetType().Name + + #check if correct type + $typeTable = @{ + "String" = "String Value" + "Byte" = "Byte Value" + "Int32" = "DWORD (32-bit) Value" + "Int64" = "QWORD (64-bit) Value" + "String[]" = "Multi-String Value" + } + + $currentType = $typeTable[$res] + if ($res -ne [String[]]) { + @{ + Id = $id + Task = $task + Status = "False" + Message = "Wrong Registry type! Registry type is '$currentType'. Expected: 'Multi-String Value'" + } | Write-Output + } + + #check if insecure or weak cipher is inside value + $regValues = $regValue -replace ' ', '' + $weakRulesFound = @() + $insecureRulesFound = @() + foreach($element in $regValues){ + if($listOfWeakCipherSuites.Contains($element)){ + $weakRulesFound += $element + } + if($listOfInsecureCipherSuites.Contains($element)){ + $insecureRulesFound += $element + } + } + #Default status + $status = "Error" + + #Output + $verbInsecure = "rules have" + $verbWeak = "rules have" + if($insecureRulesFound.Count -eq 1){$verbInsecure = "rule has"} + if($weakRulesFound.Count -eq 1){$verbWeak = "rule has"} + $insecureMessage = "$($insecureRulesFound.Count) insecure $($verbInsecure) been found! List of insecure rules:
" + $weakMessage = "$($weakRulesFound.Count) weak $($verbWeak) been found! List of weak rules:
" + + #Preparing message + foreach($member in $weakRulesFound){ + $status = "Warning" + $weakMessage += "$($member)
" + } + foreach($member in $insecureRulesFound){ + $status = "False" + $insecureMessage += "$($member)
" + } + #Combine or shorten message + if($insecureRulesFound.Count -gt 0 -or $weakRulesFound.Count -gt 0){ + $message = "" + if($weakRulesFound.Count -eq 0){ $weakMessage = "" } + if($insecureRulesFound.Count -eq 0){ $insecureMessage = "" } + + $message = $insecureMessage + $weakMessage + @{ + Id = $id + Task = $task + Status = $status + Message = $message + } | Write-Output + } + + if ($regValue -ne $reference) { + @{ + Id = $id + Task = $task + Status = "True" + Message = "Compliant" + } | Write-Output + } + } + + @{ + Id = $id + Task = $task + Status = "True" + Message = "Compliant" + } | Write-Output +} + + +#endregion + +#region Report Generation + +function Get-IIS10SystemReport { + # Section 1 + Test-IISUniqueSiteAppPool + + # Section 2 + Test-IISPasswordFormatNotClearMachineLevel + Test-IISCredentialsNotStoredMachineLevel + + # Section 3 + Test-IISDeploymentMethodRetail + Test-IISAspNetTracingDisabledMachineLevel + + # Section 4 + Test-IISIsapisNotAllowed + Test-IISCgisNotAllowed + + # Section 5 + Test-IISAdvancedLoggingEnabled + + # Section 6 + Test-IISFtpRequestsEncrypted + Test-IISFtpLogonAttemptRestriction + + # Section 7 + Test-IISSSL2Disabled + Test-IISSSL3Disabled + Test-IISTLSDisabled + Test-IISTLS1_1Disabled + Test-IISTLS1_2Enabled + Test-IISNullCipherDisabled + Test-IISDESCipherDisabled + Test-IISRC4CipherDisabled + Test-IISAES128Disabled + Test-IISAES256Enabled + Test-IISTLSCipherOrder +} + +function Get-IIS10ApplicationHostReport { + $Configuration = (Get-IISServerManager).GetApplicationHostConfiguration() + + # Section 1 + $Configuration | Test-IISDirectoryBrowsing + $Configuration | Test-IISAnonymouseUserIdentity + + # Section 2 + $Configuration | Test-IISGlobalAuthorization + $Configuration | Test-IISAuthenticatedPricipals + $Configuration | Test-IISFormsAuthenticationSSL + $Configuration | Test-IISFormsAuthenticationCookies + $Configuration | Test-IISFormsAuthenticationProtection + $Configuration | Test-IISPasswordFormatNotClear + $Configuration | Test-IISCredentialsNotStored + + # Section 3 + $Configuration | Test-IISDebugOff + $Configuration | Test-IISCustomErrorsNotOff + $Configuration | Test-IISHttpErrorsHidden + $Configuration | Test-IISAspNetTracingDisabled + $Configuration | Test-IISCookielessSessionState + + # Section 4 + $Configuration | Test-IISMaxAllowedContentLength + $Configuration | Test-IISMaxURLRequestFilter + $Configuration | Test-IISMaxQueryStringRequestFilter + $Configuration | Test-IISNonASCIICharURLForbidden + $Configuration | Test-IISRejectDoubleEncodedRequests + $Configuration | Test-IISHTTPTraceMethodeDisabled + $Configuration | Test-IISBlockUnlistedFileExtensions + $Configuration | Test-IISHandlerDenyWrite + + # Section 5 + + # Section 6 + + # Section 7 + $Configuration | Test-IISHSTSHeaderSet + +} + +function Get-VirtualPathAudit { + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Configuration] + $Configuration + ) + + process { + # Section 1 + $Configuration | Test-IISDirectoryBrowsing + $Configuration | Test-IISAnonymouseUserIdentity + + # Section 2 + $Configuration | Test-IISGlobalAuthorization + $Configuration | Test-IISAuthenticatedPricipals + $Configuration | Test-IISFormsAuthenticationSSL + $Configuration | Test-IISFormsAuthenticationCookies + $Configuration | Test-IISFormsAuthenticationProtection + $Configuration | Test-IISPasswordFormatNotClear + $Configuration | Test-IISCredentialsNotStored + + # Section 3 + $Configuration | Test-IISDebugOff + $Configuration | Test-IISCustomErrorsNotOff + $Configuration | Test-IISHttpErrorsHidden + $Configuration | Test-IISAspNetTracingDisabled + $Configuration | Test-IISCookielessSessionState + $Configuration | Test-IISCookiesHttpOnly + + # Section 4 + $Configuration | Test-IISMaxAllowedContentLength + $Configuration | Test-IISMaxURLRequestFilter + $Configuration | Test-IISMaxQueryStringRequestFilter + $Configuration | Test-IISNonASCIICharURLForbidden + $Configuration | Test-IISRejectDoubleEncodedRequests + $Configuration | Test-IISHTTPTraceMethodeDisabled + $Configuration | Test-IISBlockUnlistedFileExtensions + $Configuration | Test-IISHandlerDenyWrite + + # Section 5 + + # Section 6 + + # Section 7 + $Configuration | Test-IISHSTSHeaderSet + } +} + +function Get-SiteAudit { + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Site] + $Site + ) + + process { + $AppPools = $Site.Applications.ApplicationPoolName | Sort-Object | Get-Unique | Get-IISAppPool + + # Section 1 + $Site | Test-IISVirtualDirPartition + $Site | Test-IISHostHeaders + $AppPools | Test-IISAppPoolIdentity + + # Section 2 + $Site | Test-IISTLSForBasicAuth + + # Section 3 + $Site | Test-IISMachineKeyValidation + $Site | Test-IISMachineKeyValidationV45 + $Site | Test-IISDotNetTrustLevel + + # Section 4 + $Site | Test-IISDynamicIPRestrictionEnabled + + # Section 5 + $Site | Test-IISLogFileLocation + $Site | Test-IISETWLoggingEnabled + + # Section 6 + + + # Section 7 + + } +} + +function Get-IISHostInformation { + $infos = Get-CimInstance Win32_OperatingSystem + $disk = Get-CimInstance Win32_LogicalDisk | Where-Object -Property DeviceID -eq "C:" + + $IISinstallPath = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\InetStp").Installpath + + return [ordered]@{ + "Hostname" = [System.Net.Dns]::GetHostByName(($env:computerName)).HostName + "Operating System" = $infos.Caption + "Build Number" = $infos.BuildNumber + "IIS Version" = (Get-ItemProperty -Path ("$IISinstallPath\w3wp.exe")).VersionInfo.ProductVersion + "Free physical memory (GB)" = "{0:N3}" -f ($infos.FreePhysicalMemory / 1MB) + "Free disk space (GB)" = "{0:N1}" -f ($disk.FreeSpace / 1GB) + } +} + +[Report] @{ + Title = "IIS 10 Benchmarks" + ModuleName = "ATAPAuditor" + BasedOn = "CIS Microsoft IIS 10 Benchmark, Version: 1.1.0, Date: 12-11-2018" + HostInformation = Get-IISHostInformation + Sections = @( + [ReportSection] @{ + Title = "System Report" + AuditInfos = Get-IIS10SystemReport + } + [ReportSection] @{ + Title = "ApplicationHost" + AuditInfos = Get-IIS10ApplicationHostReport + } + foreach ($Site in Get-IISSite) { + $VirtualPaths = $Site | Get-IISSiteVirtualPaths -AllVirtualDirectories + + [ReportSection] @{ + Title = "Full site report for: $($Site.Name)" + AuditInfos = $Site | Get-SiteAudit + SubSections = @( + foreach ($VirtualPath in $VirtualPaths) { + $Configuration = (Get-IISServerManager).GetWebConfiguration($Site.Name, $VirtualPath) + + [ReportSection]@{ + Title = "Report for: $VirtualPath" + AuditInfos = $Configuration | Get-VirtualPathAudit + } + } + ) + } + } + ) +} +#endregion diff --git a/ATAPAuditor/Reports/Microsoft Internet Explorer 11.ps1 b/ATAPAuditor/Reports/Microsoft Internet Explorer 11.ps1 new file mode 100644 index 0000000..3866b12 --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Internet Explorer 11.ps1 @@ -0,0 +1,41 @@ +[Report] @{ + Title = 'Internet Explorer 11 Audit Report' + ModuleName = 'ATAPAuditor' + BasedOn = @( + 'CIS Microsoft Internet Explorer 11 Benchmark, Version: 1.0.0, Date: 2014-12-01' + 'Microsoft Windows 10 Windows Server v2004 Security Baseline FINAL, Version: 2004, Date: 2020-08-04' + 'DISA Microsoft Internet Explorer 11 Security Technical Implementation Guide, Version: V1R16, Date: 2018-06-08' + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Recommendations" + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Internet Explorer 11-CIS-1.0.0#RegistrySettings" + } + ) + } + [ReportSection] @{ + Title = "MS Recommendations" + Description = "This section contains all Microsoft recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Internet Explorer 11-MS-2004#RegistrySettings" + } + ) + } + [ReportSection] @{ + Title = "DISA Recommendations" + Description = "This section contains all DISA recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Internet Explorer 11-DISA-V1R16#RegistrySettings" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft Office.ps1 b/ATAPAuditor/Reports/Microsoft Office.ps1 new file mode 100644 index 0000000..5084a8e --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Office.ps1 @@ -0,0 +1,19 @@ +[Report] @{ + Title = 'Microsoft Office Audit Report' + ModuleName = 'ATAPAuditor' + BasedOn = @( + 'CIS Microsoft Office Enterprise Benchmark, Version: 1.2.0, Date: 2024-07-19' + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Office Enterprise-CIS-1.2.0#RegistrySettings" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft SQL Server 2016.ps1 b/ATAPAuditor/Reports/Microsoft SQL Server 2016.ps1 new file mode 100644 index 0000000..db3aab4 --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft SQL Server 2016.ps1 @@ -0,0 +1,2754 @@ +[CmdletBinding(DefaultParameterSetName = "Default")] +param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] + $SqlInstance, + + [string] + $MachineName = $env:COMPUTERNAME, + + [Parameter(Mandatory = $true, ParameterSetName = "ByAuditInfo")] + [Hashtable[]] + $InstanceAudits +) + +if (get-module -ListAvailable SQLPS) { + Import-Module SQLPS -Force +} +elseif (get-module -ListAvailable SQLServer) { + Import-Module SQLServer -Force +} + +# CIS Microsoft SQL Server 2016 Benchmark +# v1.0.0 - 08-11-2017 +# +# + + +# +# +# CIS Microsoft SQL Server 2016 Benchmark - Audit section +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + + +# +# 1 Installation, Updates and Patches +# +# This section contains recommendations related to installing and patching SQL Server. +# + + +#region 2 Surface Area Reduction +# +# SQL Server offers various configuration options, some of them can be controlled by the +# sp_configure stored procedure. This section contains the listing of the corresponding recommendations. + +function Test-SQLAdHocDistributedQueriesDisabled { + <# +.Synopsis + Ensure 'Ad Hoc Distributed Queries' Server Configuration Option is set to '0'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.1 - Ensure 'Ad Hoc Distributed Queries' Server Configuration Option is set to '0'. + + Enabling Ad Hoc Distributed Queries allows users to query data and execute statements on external data sources. This functionality should be disabled. + + This feature can be used to remotely access and exploit vulnerabilities on remote SQL Server instances and to run unsafe Visual Basic for Application functions. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.1") + $obj | Add-Member NoteProperty Task("Ensure 'Ad Hoc Distributed Queries' Server Configuration Option is set to '0'") + + $query = "SELECT name, CAST(value as int) as value_configured, CAST(value_in_use as int) as value_in_use FROM sys.configurations WHERE name = 'Ad Hoc Distributed Queries';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + + if ( ($sqlResult.value_configured -eq 0) -and ($sqlResult.value_in_use -eq 0) ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Values do not match, found: `n value_configured: " + $sqlResult.value_configured + ",`n value_in_use:" + $sqlResult.value_in_use) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLClrEnabled { + <# +.Synopsis + Ensure 'CLR Enabled' Server Configuration Option is set to '0'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.2 - Ensure 'CLR Enabled' Server Configuration Option is set to '0'. + + The clr enabled option specifies whether user assemblies can be run by SQL Server. + + Enabling use of CLR assemblies widens the attack surface of SQL Server and puts it at risk from both inadvertent and malicious assemblies. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.2") + $obj | Add-Member NoteProperty Task("Ensure 'CLR Enabled' Server Configuration Option is set to '0'") + + $query = "SELECT name, CAST(value as int) as value_configured, CAST(value_in_use as int) as value_in_use FROM sys.configurations WHERE name = 'clr enabled';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + if ( ($sqlResult.value_configured -eq 0) -and ($sqlResult.value_in_use -eq 0) ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Values do not match, found: `n value_configured: " + $sqlResult.value_configured + "`n value_in_use:" + $sqlResult.value_in_use) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLCrossDBOwnershipDisabled { + <# +.Synopsis + Ensure 'Cross DB Ownership Chaining' Server Configuration Option is set to '0'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.3 - Ensure 'Cross DB Ownership Chaining' Server Configuration Option is set to '0' + + The cross db ownership chaining option controls cross-database ownership chaining + + across all databases at the instance (or server) level. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.3") + $obj | Add-Member NoteProperty Task("Ensure 'Cross DB Ownership Chaining' Server Configuration Option is set to '0'") + + $query = "SELECT name, CAST(value as int) as value_configured, CAST(value_in_use as int) as value_in_use FROM sys.configurations WHERE name = 'cross db ownership chaining';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( ($sqlResult.value_configured -eq 0) -and ($sqlResult.value_in_use -eq 0) ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Values do not match, found: `n value_configured: " + $sqlResult.value_configured + "`n value_in_use:" + $sqlResult.value_in_use) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLDatabaseMailXPsDisabled { + <# +.Synopsis + Ensure 'Database Mail XPs' Server Configuration Option is set to '0'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.4 - Ensure 'Database Mail XPs' Server Configuration Option is set to '0'. + + The Database Mail XPs option controls the ability to generate and transmit email messages from SQL Server. + + Disabling the Database Mail XPs option reduces the SQL Server surface, eliminates a DOS attack vector and channel to exfiltrate data from the database server to a remote host. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.4") + $obj | Add-Member NoteProperty Task("Ensure 'Database Mail XPs' Server Configuration Option is set to '0'") + + $query = "SELECT name, CAST(value as int) as value_configured, CAST(value_in_use as int) as value_in_use FROM sys.configurations WHERE name = 'Database Mail XPs';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( ($sqlResult.value_configured -eq 0) -and ($sqlResult.value_in_use -eq 0) ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Values do not match, found: `n value_configured: " + $sqlResult.value_configured + "`n value_in_use:" + $sqlResult.value_in_use) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + + Write-Output $obj +} + +function Test-SQLOleAutomationProceduresDisabled { + <# +.Synopsis + Ensure 'Ole Automation Procedures' Server Configuration Option is set to '0'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.5 - Ensure 'Ole Automation Procedures' Server Configuration Option is set to '0'. + + The Ole Automation Procedures option controls whether OLE Automation objects can be instantiated within Transact-SQL batches. These are extended stored procedures that allow SQL Server users to execute functions external to SQL Server. + + Disabling the Database Mail XPs option reduces the SQL Server surface, eliminates a DOS attack vector and channel to exfiltrate data from the database server to a remote host. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.5") + $obj | Add-Member NoteProperty Task("Ensure 'Ole Automation Procedures' Server Configuration Option is set to '0'") + + $query = "SELECT name, CAST(value as int) as value_configured, CAST(value_in_use as int) as value_in_use FROM sys.configurations WHERE name = 'Ole Automation Procedures';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( ($sqlResult.value_configured -eq 0) -and ($sqlResult.value_in_use -eq 0) ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Values do not match, found: `n value_configured: " + $sqlResult.value_configured + "`n value_in_use:" + $sqlResult.value_in_use) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLRemoteAccessDisabled { + <# +.Synopsis + Ensure 'Remote Access' Server Configuration Option is set to '0'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.6 - Ensure 'Remote Access' Server Configuration Option is set to '0'. + + The remote access option controls the execution of local stored procedures on remote servers or remote stored procedures on local server. + + Functionality can be abused to launch a Denial-of-Service (DoS) attack on remote servers by off-loading query processing to a target. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.6") + $obj | Add-Member NoteProperty Task("Ensure 'Remote Access' Server Configuration Option is set to '0'") + + $query = "SELECT name, CAST(value as int) as value_configured, CAST(value_in_use as int) as value_in_use FROM sys.configurations WHERE name = 'remote access';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( ($sqlResult.value_configured -eq 0) -and ($sqlResult.value_in_use -eq 0) ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Values do not match, found: `n value_configured: " + $sqlResult.value_configured + "`n value_in_use: " + $sqlResult.value_in_use) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLRemoteAdminConnectionsDisabled { + <# +.Synopsis + Ensure 'Remote Admin Connections' Server Configuration Option is set to '0'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.7 - Ensure 'Remote Admin Connections' Server Configuration Option is set to '0' + + The remote admin connections option controls whether a client application on a remote computer can use the Dedicated Administrator Connection (DAC). + + The Dedicated Administrator Connection (DAC) lets an administrator access a running server to execute diagnostic functions or Transact-SQL statements, or to troubleshoot + problems on the server, even when the server is locked or running in an abnormal state and not responding to a SQL Server Database Engine connection. In a cluster scenario, the + administrator may not actually be logged on to the same node that is currently hosting the SQL Server instance and thus is considered "remote". Therefore, this setting should usually + be enabled (1) for SQL Server failover clusters; otherwise it should be disabled (0) which is the default. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.7") + $obj | Add-Member NoteProperty Task("Ensure 'Remote Admin Connections' Server Configuration Option is set to '0'") + + $query = "SELECT name, CAST(value as int) as value_configured, CAST(value_in_use as int) as value_in_use FROM sys.configurations WHERE name = 'remote admin connections' AND SERVERPROPERTY('IsClustered') = 0;" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( ($sqlResult.value_configured -eq 0) -and ($sqlResult.value_in_use -eq 0) ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Values do not match, found: `n value_configured: " + $sqlResult.value_configured + "`n value_in_use:" + $sqlResult.value_in_use) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLScanForStartupProcsDisabled { + <# +.Synopsis + Ensure 'Scan For Startup Procs' Server Configuration Option is set to '0'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.8 - Ensure 'Scan For Startup Procs' Server Configuration Option is set to '0'. + + The scan for startup procs option, if enabled, causes SQL Server to scan for and automatically run all stored procedures that are set to execute upon service startup. + + Enforcing this control reduces the threat of an entity leveraging these facilities for malicious purposes. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.8") + $obj | Add-Member NoteProperty Task("Ensure 'Scan For Startup Procs' Server Configuration Option is set to '0'") + + $query = "SELECT name, CAST(value as int) as value_configured, CAST(value_in_use as int) as value_in_use FROM sys.configurations WHERE name = 'scan for startup procs';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( ($sqlResult.value_configured -eq 0) -and ($sqlResult.value_in_use -eq 0) ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Values do not match, found: `n value_configured: " + $sqlResult.value_configured + "`n value_in_use:" + $sqlResult.value_in_use) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLTrustworthyDatabaseOff { + <# +.Synopsis + Ensure 'Trustworthy' Database Property is set to 'Off'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.9 - Ensure 'Trustworthy' Database Property is set to 'Off'. + + The TRUSTWORTHY database option allows database objects to access objects in other databases under certain circumstances. + + Provides protection from malicious CLR assemblies or extended procedures. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.9") + $obj | Add-Member NoteProperty Task("Ensure 'Trustworthy' Database Property is set to 'Off'") + + $query = "SELECT name FROM sys.databases WHERE is_trustworthy_on = 1 AND name != 'msdb';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Found $sqlResult.name") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLServerProtocolsDisabled { + <# +.Synopsis + Ensure Unnecessary SQL Server Protocols are set to 'Disabled'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.10 - Ensure Unnecessary SQL Server Protocols are set to 'Disabled'. + + SQL Server supports Shared Memory, Named Pipes, and TCP/IP protocols. However, SQL Server should be configured to use the bare minimum required based on the organization's needs. + + Using fewer protocols minimizes the attack surface of SQL Server and, in some cases, can protect it from remote attacks. +#> + [CmdletBinding()] + param( + [string] $SqlInstance = "MSSQLSERVER", + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.10") + $obj | Add-Member NoteProperty Task("Ensure Unnecessary SQL Server Protocols are set to 'Disabled'") + + $protocols = "np", "sm", "tcp" + $smo = 'Microsoft.SqlServer.Management.Smo.' + $wmi = New-Object ($smo + 'Wmi.ManagedComputer') + + try { + $singleWmi = $wmi | Where-Object {$_.Name -eq $machineName} + $foundProtocols = @() + foreach ($protocol in $protocols) { + $uri = "ManagedComputer[@Name='$machineName']/ServerInstance[@Name='$sqlInstance']/ServerProtocol[@Name='$protocol']" + $p = $singleWmi.GetsmoObject($uri) + if ($p.isEnabled) { + $foundProtocols += $p.displayName + } + } + [string]$s = $null + $s = $foundProtocols -join ", " + + if ($foundProtocols.Count -eq 0) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + elseif ($foundProtocols.Count -eq 1) { + $obj | Add-Member NoteProperty Status("Only one Protocol is enabled: " + $s) + $obj | Add-Member NoteProperty Audit("True") + } + elseif ($foundProtocols.Count -eq 2) { + $obj | Add-Member NoteProperty Status("Following protocols are enabled: " + $s) + $obj | Add-Member NoteProperty Audit("Warning") + } + else { + $obj | Add-Member NoteProperty Status("Following protocols are enabled: " + $s) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Mangement.Automation.MethodInvocationException] { + $obj | Add-Member NoteProperty Status("MachineName not found or sqlInstance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLUseNonStandardPorts { + <# +.Synopsis + Ensure SQL Server is configured to use non-standard ports. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.11 - Ensure SQL Server is configured to use non-standard ports. + + The TRUSTWORTHY database option allows database objects to access objects in other databases under certain circumstances. + + Provides protection from malicious CLR assemblies or extended procedures. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.11") + $obj | Add-Member NoteProperty Task("Ensure SQL Server is configured to use non-standard ports") + + $query = "DECLARE @value nvarchar(256); + EXECUTE master.dbo.xp_instance_regread + N'HKEY_LOCAL_MACHINE', + N'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQLServer\SuperSocketNetLib\Tcp\IPAll', + N'TcpPort', + @value OUTPUT, + N'no_output'; + SELECT @value AS TCP_Port WHERE @value = '1433';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("TCP port 1433 in use") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLHideInstanceEnabled { + <# +.Synopsis + Ensure 'Hide Instance' option is set to 'Yes' for Production SQL Server instances. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.12 - Ensure 'Hide Instance' option is set to 'Yes' for Production SQL Server instances. + + Non-clustered SQL Server instances within production environments should be designated as hidden to prevent advertisement by the SQL Server Browser service. + + Designating production SQL Server instances as hidden leads to a more secure installation because they cannot be enumerated. However, clustered instances may break if this option is selected. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.12") + $obj | Add-Member NoteProperty Task("Ensure 'Hide Instance' option is set to 'Yes' for Production SQL Server instances") + + $query = "DECLARE @getValue INT; + EXEC master..xp_instance_regread + @rootkey = N'HKEY_LOCAL_MACHINE', + @key = N'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQLServer\SuperSocketNetLib', + @value_name = N'HideInstance', + @value = @getValue OUTPUT; + SELECT @getValue AS Hide_Instance;" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $sqlResult.Hide_Instance -eq 1 ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Instance not hidden") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLSaLoginAccountDisabled { + <# +.Synopsis + Ensure the 'sa' Login Account is set to 'Disabled'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.13 - Ensure the 'sa' Login Account is set to 'Disabled'. + + The sa account is a widely known and often widely used SQL Server account with sysadmin privileges. This is the original login created during installation and always has the principal_id=1 and sid=0x01. + + Enforcing this control reduces the probability of an attacker executing brute force attacks against a well-known principal. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.13") + $obj | Add-Member NoteProperty Task("Ensure the 'sa' Login Account is set to 'Disabled'") + + $query = "SELECT name, is_disabled FROM sys.server_principals WHERE sid = 0x01 AND is_disabled = 0;" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("SA Login Account enabled") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLSaLoginAccountRenamed { + <# +.Synopsis + Ensure the 'sa' Login Account has been renamed. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.14 - Ensure the 'sa' Login Account has been renamed. + + The sa account is a widely known and often widely used SQL Server account with sysadmin privileges. This is the original login created during installation and always has the principal_id=1 and sid=0x01. + + It is more difficult to launch password-guessing and brute-force attacks against the sa login if the name is not known. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.14") + $obj | Add-Member NoteProperty Task(" Ensure the 'sa' Login Account has been renamed") + + $query = "SELECT name FROM sys.server_principals WHERE sid = 0x01" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ($sqlResult.name -ne "sa") { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("SA Login Account not renamed") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLXpCommandShellDisabled { + <# +.Synopsis + Ensure 'xp_cmdshell' Server Configuration Option is set to '0'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.15 - Ensure 'xp_cmdshell' Server Configuration Option is set to '0'. + + The xp_cmdshell option controls whether the xp_cmdshell extended stored procedure can be used by an authenticated SQL Server user to execute operating-system command shell commands and return results as rows within the SQL client. + + The xp_cmdshell procedure is commonly used by attackers to read or write data to/from the underlying Operating System of a database server. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.15") + $obj | Add-Member NoteProperty Task("Ensure 'xp_cmdshell' Server Configuration Option is set to '0'") + + $query = "SELECT name, CAST(value as int) as value_configured, CAST(value_in_use as int) as value_in_use FROM sys.configurations WHERE name = 'xp_cmdshell';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( ($sqlResult.value_configured -eq 0) -and ($sqlResult.value_in_use -eq 0) ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Values do not match, found: `n value_configured: " + $sqlResult.value_configured + "`n value_in_use:" + $sqlResult.value_in_use) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLAutoCloseOff { + <# +.Synopsis + Ensure 'AUTO_CLOSE' is set to 'OFF' on contained databases. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.16 - Ensure 'AUTO_CLOSE' is set to 'OFF' on contained databases. + + AUTO_CLOSE determines if a given database is closed or not after a connection terminates. If enabled, subsequent connections to the given database will require the database to be + reopened and relevant procedure caches to be rebuilt. + + Because authentication of users for contained databases occurs within the database not at the server\instance level, the database must be opened every time to authenticate a user. + The frequent opening/closing of the database consumes additional server resources and may contribute to a denial of service. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.16") + $obj | Add-Member NoteProperty Task(" Ensure 'AUTO_CLOSE' is set to 'OFF' on contained databases") + + $query = "SELECT name, containment, containment_desc, is_auto_close_on FROM sys.databases WHERE containment <> 0 and is_auto_close_on = 1;" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult.name) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("AUTO_CLOSE not set to OFF") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLNoSaAccounnt { + <# +.Synopsis + Ensure no login exists with the name 'sa'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 2 Surface Area Reduction + + 2.17 - Ensure no login exists with the name 'sa'. + + The sa login (e.g. principal) is a widely known and often widely used SQL Server account.Therefore, there should not be a login called sa even when the original sa login (principal_id = 1) has been renamed. + + Enforcing this control reduces the probability of an attacker executing brute force attacks against a well-known principal name. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("2.17") + $obj | Add-Member NoteProperty Task("Ensure no login exists with the name 'sa'") + + $query = "SELECT principal_id, name FROM sys.server_principals WHERE name = 'sa';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult.name) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Found login with name 'sa'") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} +#endregion + +#region 3 Authentication and Authorization +# +# This section contains recommendations related to SQL Server's authentication and authorization mechanisms. +# + +function Test-SQLServerAuthentication { + <# +.Synopsis + Ensure 'Server Authentication' Property is set to 'Windows Authentication Mode'. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 3 Authentication and Authorization + + 3.1 - Ensure 'Server Authentication' Property is set to 'Windows Authentication Mode'. + + Uses Windows Authentication to validate attempted connections. + + Windows provides a more robust authentication mechanism than SQL Server authentication. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("3.1") + $obj | Add-Member NoteProperty Task("Ensure 'Server Authentication' Property is set to 'Windows Authentication Mode'") + + $query = "SELECT SERVERPROPERTY('IsIntegratedSecurityOnly') as [login_mode];" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $sqlResult.login_mode -eq 1 ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + elseif ( $sqlResult.login_mode -eq 0 ) { + $obj | Add-Member NoteProperty Status("Login mode set to Mixed Mode Authentication") + $obj | Add-Member NoteProperty Audit("False") + } + else { + $obj | Add-Member NoteProperty Status("An unknown error occured") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLGuestPermissionOnDatabases { + <# +.Synopsis + Ensure CONNECT permissions on the 'guest' user is Revoked within all SQL Server databases excluding the master, msdb and tempdb. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 3 Authentication and Authorization + + 3.2 - Ensure CONNECT permissions on the 'guest' user is Revoked within all SQL Server databases excluding the master, msdb and tempdb. + + Remove the right of the guest user to connect to SQL Server databases, except for master, msdb, and tempdb. + + A login assumes the identity of the guest user when a login has access to SQL Server but does not have access to a database through its own account and the database has a guest + user account. Revoking the CONNECT permission for the guest user will ensure that a login is not able to access database information without explicit access to do so. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $databases = Get-SqlDatabase -ServerInstance $instanceName -ErrorAction Stop | Select-Object -ExpandProperty name + } + else { + $databases = Get-SqlDatabase -ServerInstance $MachineName -ErrorAction Stop | Select-Object -ExpandProperty name + } + + $databases = {$databases}.Invoke() + if ($databases.Remove("master")) { + } + if ($databases.Remove("msdb")) { + } + if ($databases.Remove("tempdb")) { + } + $index = 1 + + foreach ($database in $databases) { + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("3.2.$index") + $obj | Add-Member NoteProperty Task("Ensure CONNECT permissions on the 'guest' user is revoked for database $database") + $query = "USE [$database]; " + ` + "SELECT DB_NAME() AS DatabaseName, 'guest' AS Database_User, [permission_name], [state_desc] + FROM sys.database_permissions + WHERE [grantee_principal_id] = DATABASE_PRINCIPAL_ID('guest') + AND [state_desc] LIKE 'GRANT%' + AND [permission_name] = 'CONNECT' + AND DB_NAME() NOT IN ('master','tempdb','msdb');" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Got $sqlResult") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj + + $index++ + } + } + catch { + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("3.2") + $obj | Add-Member NoteProperty Task("Ensure CONNECT permissions on the 'guest' user is revoked for database $database") + $obj | Add-Member NoteProperty Status("Failed to connect to server $instanceName") + $obj | Add-Member NoteProperty Audit("Warning") + Write-Output $obj + } +} + +function Test-SQLDropOrphanedUsers { + <# +.Synopsis + Ensure 'Orphaned Users' are Dropped From SQL Server Databases. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 3 Authentication and Authorization + + 3.3 - Ensure 'Orphaned Users' are Dropped From SQL Server Databases. + + A database user for which the corresponding SQL Server login is undefined or is incorrectly defined on a server instance cannot log in to the instance and is referred to as orphaned and should be removed. + + Orphan users should be removed to avoid potential misuse of those broken users in any way. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $databases = Get-SqlDatabase -ServerInstance $instanceName -ErrorAction Stop | Select-Object -ExpandProperty name + } + else { + $databases = Get-SqlDatabase -ServerInstance $MachineName -ErrorAction Stop | Select-Object -ExpandProperty name + } + + $index = 1 + + foreach ($database in $databases) { + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("3.3.$index") + $obj | Add-Member NoteProperty Task("Ensure 'Orphaned Users' are dropped for database $database") + + $query = "USE [$database]; + GO + EXEC sp_change_users_login @Action='Report';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Got $sqlResult") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + + Write-Output $obj + + $index++ + } + } + catch { + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("3.3") + $obj | Add-Member NoteProperty Task("Ensure 'Orphaned Users' are dropped for database $database") + $obj | Add-Member NoteProperty Status("Failed to connect to server $instanceName") + $obj | Add-Member NoteProperty Audit("Warning") + Write-Output $obj + } +} + +function Test-SQLAuthenticationDisabled { + <# +.Synopsis + Ensure SQL Authentication is not used in contained databases. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 3 Authentication and Authorization + + 3.4 - Ensure SQL Authentication is not used in contained databases. + + Contained databases do not enforce password complexity rules for SQL Authenticated users. + + The absence of an enforced password policy may increase the likelihood of a weak credential being established in a contained database. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $databases = Get-SqlDatabase -ServerInstance $instanceName -ErrorAction Stop | Select-Object -ExpandProperty name + } + else { + $databases = Get-SqlDatabase -ServerInstance $MachineName -ErrorAction Stop | Select-Object -ExpandProperty name + } + + if ($databases.Count -eq 0) { + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("7.1") + $obj | Add-Member NoteProperty Task("Ensure 'Symmetric Key encryption algorithm' is set to 'AES_128' or higher in non-system databases") + $obj | Add-Member NoteProperty Status("No databases found") + $obj | Add-Member NoteProperty Audit("Warning") + Write-Output $obj + } + + $index = 1 + + foreach ($database in $databases) { + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("3.4.$index") + $obj | Add-Member NoteProperty Task("Ensure SQL Authentication is not used for database $database") + + $query = "USE [$database]; + GO + SELECT name AS DBUser + FROM sys.database_principals + WHERE name NOT IN ('dbo','Information_Schema','sys','guest') + AND type IN ('U','S','G') + AND authentication_type = 2; + GO" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Got $sqlResult") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + + Write-Output $obj + + $index++ + } + } + catch { + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("3.4") + $obj | Add-Member NoteProperty Task("Ensure CONNECT permissions on the 'guest' user is revoked for database $database") + $obj | Add-Member NoteProperty Status("Ensure SQL Authentication is not used for database $database") + $obj | Add-Member NoteProperty Audit("Warning") + Write-Output $obj + } +} + +function Test-SQLServerServiceAccountIsNotAnAdministrator { + <# +.Synopsis + Ensure the SQL Server’s MSSQL Service Account is Not an Administrator +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 3 Authentication and Authorization + + 3.5 - Ensure the SQL Server’s MSSQL Service Account is Not an Administrator + + The service account and/or service SID used by the MSSQLSERVER service for a default instance or MSSQL$ service for a named instance should not be a member of the Windows Administrator group either directly or indirectly (via a group). This also means that the account known as LocalSystem (aka NT AUTHORITY\SYSTEM) should not be used for the MSSQL service as this account has higher privileges than the SQL Server service requires. + + Following the principle of least privilege, the service account should have no more privileges than required to do its job. For SQL Server services, the SQL Server Setup will assign the required permissions directly to the service SID. No additional permissions or privileges should be necessary. +#> + [CmdletBinding()] + param( + [string] $MachineName = $env:COMPUTERNAME + ) + $obj = New-Object psobject + $obj | Add-Member NoteProperty ID("3.5") + $obj | Add-Member NoteProperty Task("Ensure the SQL Server’s MSSQL Service Account is Not an Administrator") + + + $smo = 'Microsoft.SqlServer.Management.Smo.' + $wmi = New-Object ($smo + 'Wmi.ManagedComputer') + $singleWmi = $wmi | Where-Object {$_.Name -eq $machineName} + $sqlServer = $singleWmi.Services | Where-Object {$_.Type -eq "SqlServer"} + $serviceAccountNames = @() + foreach ($sqlS in $sqlServer) { + $serviceAccountNames += $sqlS.ServiceAccount.Substring($sqlS.serviceAccount.IndexOf("\") + 1 ) + } + + $ADSIComputer = [ADSI]("WinNT://$machineName,computer") + try { + $group = $ADSIComputer.psbase.children.find('Administrators', 'Group') + } + catch { + try { + $group = $ADSIComputer.psbase.children.find('Administratoren', 'Group') + } + catch [System.Mangement.Automation.MethodInvocationException] { + $obj | Add-Member NoteProperty Status("MachineName not found") + $obj | Add-Member NoteProperty Audit("Warning") + return Write-Output $obj + } + } + + $members = $group.psbase.invoke("members") | ForEach-Object { + $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) + } + $admins = @() + + foreach ($member in $members) { + try { + # Try if $member is a AD group and get all members of this group including all nested groups + $admins += (Get-ADGroupMember $member -Recursive | Select-Object -ExpandProperty SamAccountName) + } + catch { + # TODO catch unterscheiden nach nicht gefunden oder active directory Fehler + # If it is not a AD group, it has to be a local account, so add it (we assume local groups are not used inside the company) + $admins += $member + } + } + foreach ($serviceAccountName in $serviceAccountNames) { + foreach ($admin in $admins) { + if ($admin -eq $serviceAccountName) { + $sqlAdmins += $serviceAccountName + } + } + } + if ($null -eq $sqlAdmins) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Following service accounts are administrator: " + $sqlAdmins) + $obj | Add-Member NoteProperty Audit("False") + } + Write-Output $obj +} + +function Test-SQLAgentServiceAccountIsNotAnAdministrator { + <# +.Synopsis + Ensure the SQL Server’s SQLAgent Service Account is Not an Administrator +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 3 Authentication and Authorization + + 3.6 - Ensure the SQL Server’s SQLAgent Service Account is Not an Administrator + + The service account and/or service SID used by the SQLSERVERAGENT service for a default instance or SQLAGENT$ service for a named instance should not be a member of the Windows Administrator group either directly or indirectly (via a group). This also means that the account known as LocalSystem (aka NT AUTHORITY\SYSTEM) should not be used for the SQLAGENT service as this account has higher privileges than the SQL Server service requires. + + Following the principle of least privilege, the service account should have no more privileges than required to do its job. For SQL Server services, the SQL Server Setup will assign the required permissions directly to the service SID. No additional permissions or privileges should be necessary. +#> + [CmdletBinding()] + param( + [string] $MachineName = $env:COMPUTERNAME + ) + $obj = New-Object psobject + $obj | Add-Member NoteProperty ID("3.6") + $obj | Add-Member NoteProperty Task("Ensure the SQL Server’s SQLAgent Service Account is Not an Administrator") + + $smo = 'Microsoft.SqlServer.Management.Smo.' + $wmi = New-Object ($smo + 'Wmi.ManagedComputer') + $singleWmi = $wmi | Where-Object {$_.Name -eq $machineName} + $sqlAgent = $singleWmi.Services | Where-Object {$_.Type -eq "SqlAgent"} + $sqlAgentNames = @() + foreach ($sqlS in $sqlAgent) { + $sqlAgentNames += $sqlS.ServiceAccount.Substring($sqlS.serviceAccount.IndexOf("\") + 1 ) + } + + $ADSIComputer = [ADSI]("WinNT://$machineName,computer") + + try { + $group = $ADSIComputer.psbase.children.find('Administrators', 'Group') + } + catch { + try { + $group = $ADSIComputer.psbase.children.find('Administratoren', 'Group') + } + catch [System.Mangement.Automation.MethodInvocationException] { + $obj | Add-Member NoteProperty Status("MachineName not found") + $obj | Add-Member NoteProperty Audit("Warning") + return Write-Output $obj + } + } + + $members = $group.psbase.invoke("members") | ForEach-Object { + $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) + } + $admins = @() + + foreach ($member in $members) { + try { + # Try if $member is a AD group and get all members of this group including all nested groups + $admins += (Get-ADGroupMember $member -Recursive | Select-Object -ExpandProperty SamAccountName) + } + catch { + # TODO catch unterscheiden nach nicht gefunden oder active directory Fehler + # If it is not a AD group, it has to be a local account, so add it (we assume local groups are not used inside the company) + $admins += $member + } + } + foreach ($sqlAgentName in $sqlAgentNames) { + foreach ($admin in $admins) { + if ($admin -eq $sqlAgentName) { + $sqlAdmins += $sqlAgentName + } + } + } + if ($null -eq $sqlAdmins) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Following service accounts are administrator: " + $sqlAdmins) + $obj | Add-Member NoteProperty Audit("False") + } + Write-Output $obj +} + +function Test-SQLFullTextServiceAccountIsNotAnAdministrator { + <# +.Synopsis + Ensure the SQL Server’s Full-Text Service Account is Not an Administrator +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 3 Authentication and Authorization + + 3.7 - Ensure the SQL Server’s Full-Text Service Account is Not an Administrator + + The service account and/or service SID used by the MSSQLFDLauncher service for a default instance or MSSQLFDLauncher$ service for a named instance should not be a member of the Windows Administrator group either directly or indirectly (via a group). This also means that the account known as LocalSystem (aka NT AUTHORITY\SYSTEM) should not be used for the Full-Text service as this account has higher privileges than the SQL Server service requires. + + Following the principle of least privilege, the service account should have no more privileges than required to do its job. For SQL Server services, the SQL Server Setup will assign the required permissions directly to the service SID. No additional permissions or privileges should be necessary. +#> + [CmdletBinding()] + param( + [string] $MachineName = $env:COMPUTERNAME + ) + $obj = New-Object psobject + $obj | Add-Member NoteProperty ID("3.7") + $obj | Add-Member NoteProperty Task("Ensure the SQL Server’s Full-Text Service Account is Not an Administrator") + + $smo = 'Microsoft.SqlServer.Management.Smo.' + $wmi = New-Object ($smo + 'Wmi.ManagedComputer') + $singleWmi = $wmi | Where-Object {$_.Name -eq $machineName} + $sqlServices = $singleWmi.Services | Where-Object {$_.Type -eq "9"} + $sqlServiceNames = @() + foreach ($sqlS in $sqlServices) { + $sqlServiceNames += $sqlS.ServiceAccount.Substring($sqlS.serviceAccount.IndexOf("\") + 1 ) + } + + $ADSIComputer = [ADSI]("WinNT://$machineName,computer") + + try { + $group = $ADSIComputer.psbase.children.find('Administrators', 'Group') + } + catch { + try { + $group = $ADSIComputer.psbase.children.find('Administratoren', 'Group') + } + catch [System.Mangement.Automation.MethodInvocationException] { + $obj | Add-Member NoteProperty Status("MachineName not found") + $obj | Add-Member NoteProperty Audit("Warning") + return Write-Output $obj + } + } + + $members = $group.psbase.invoke("members") | ForEach-Object { + $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) + } + $admins = @() + + foreach ($member in $members) { + try { + # Try if $member is a AD group and get all members of this group including all nested groups + $admins += (Get-ADGroupMember $member -Recursive | Select-Object -ExpandProperty SamAccountName) + } + catch { + # TODO catch unterscheiden nach nicht gefunden oder active directory Fehler + # If it is not a AD group, it has to be a local account, so add it (we assume local groups are not used inside the company) + $admins += $member + } + } + foreach ($sqlServiceName in $sqlServiceNames) { + foreach ($admin in $admins) { + if ($admin -eq $sqlServiceName) { + $sqlAdmins += $sqlServiceName + } + } + } + if ($null -eq $sqlAdmins) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Following service accounts are administrator: " + $sqlAdmins) + $obj | Add-Member NoteProperty Audit("False") + } + Write-Output $obj +} + +function Test-SQLPermissionsForRolePublic { + <# +.Synopsis + Ensure only the default permissions specified by Microsoft are granted to the public server role. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 3 Authentication and Authorization + + 3.8 - Ensure only the default permissions specified by Microsoft are granted to the public server role. + + public is a special fixed server role containing all logins. Unlike other fixed server roles, permissions can be changed for the public role. In keeping with the principle of least + privileges, the public server role should not be used to grant permissions at the server scope as these would be inherited by all users. + + Every SQL Server login belongs to the public role and cannot be removed from this role. Therefore, any permissions granted to this role will be available to all logins unless they + have been explicitly denied to specific logins or user-defined server roles. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("3.8") + $obj | Add-Member NoteProperty Task("Ensure only the default permissions specified by Microsoft are granted to the public server role") + + $query = "SELECT * + FROM master.sys.server_permissions + WHERE (grantee_principal_id = SUSER_SID(N'public') and state_desc LIKE + 'GRANT%') + AND NOT (state_desc = 'GRANT' and [permission_name] = 'VIEW ANY DATABASE' + and class_desc = 'SERVER') + AND NOT (state_desc = 'GRANT' and [permission_name] = 'CONNECT' and + class_desc = 'ENDPOINT' and major_id = 2) + AND NOT (state_desc = 'GRANT' and [permission_name] = 'CONNECT' and + class_desc = 'ENDPOINT' and major_id = 3) + AND NOT (state_desc = 'GRANT' and [permission_name] = 'CONNECT' and + class_desc = 'ENDPOINT' and major_id = 4) + AND NOT (state_desc = 'GRANT' and [permission_name] = 'CONNECT' and + class_desc = 'ENDPOINT' and major_id = 5);" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Found Permission:" + $sqlResult.permission_name) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLWindowsBuiltinNoSqlLogin { + <# +.Synopsis + Ensure Windows BUILTIN groups are not SQL Logins. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 3 Authentication and Authorization + + 3.9 - Ensure Windows BUILTIN groups are not SQL Logins. + + Prior to SQL Server 2008, the BUILTIN\Administrators group was added a SQL Server login with sysadmin privileges during installation by default. Best practices promote + creating an Active Directory level group containing approved DBA staff accounts and using this controlled AD group as the login with sysadmin privileges. The AD group should be + specified during SQL Server installation and the BUILTIN\Administrators group would therefore have no need to be a login. + + The BUILTIN groups (Administrators, Everyone, Authenticated Users, Guests, etc.) generally contain very broad memberships which would not meet the best practice of ensuring only + necessary users have been granted access to a SQL Server instance. These groups should not be used for any level of access into a SQL Server Database Engine instance. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("3.9") + $obj | Add-Member NoteProperty Task("Ensure Windows BUILTIN groups are not SQL Logins") + + $query = "SELECT pr.[name], pe.[permission_name], pe.[state_desc] + FROM sys.server_principals pr + JOIN sys.server_permissions pe + ON pr.principal_id = pe.grantee_principal_id + WHERE pr.name like 'BUILTIN%';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Found Account(s):" + $sqlResult.name) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLWindowsLocalGroupsNoSqlLogin { + <# +.Synopsis + Ensure Windows local groups are not SQL Logins. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 3 Authentication and Authorization + + 3.10 - Ensure Windows local groups are not SQL Logins. + + Local Windows groups should not be used as logins for SQL Server instances. + + Allowing local Windows groups as SQL Logins provides a loophole whereby anyone with OS level administrator rights (and no SQL Server rights) could add users to the local + Windows groups and thereby give themselves or others access to the SQL Server instance. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("3.10") + $obj | Add-Member NoteProperty Task("Ensure Windows local groups are not SQL Logins") + + $query = "USE [master] + GO + SELECT pr.[name] AS LocalGroupName, pe.[permission_name], pe.[state_desc] + FROM sys.server_principals pr + JOIN sys.server_permissions pe + ON pr.[principal_id] = pe.[grantee_principal_id] + WHERE pr.[type_desc] = 'WINDOWS_GROUP' + AND pr.[name] like CAST(SERVERPROPERTY('MachineName') AS nvarchar) + '%';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Found Group(s):" + $sqlResult.LocalGroupName) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLPublicRoleMsdbDatabase { + <# +.Synopsis + Ensure the public role in the msdb database is not granted access to SQL Agent proxies. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 3 Authentication and Authorization + + 3.11 - Ensure the public role in the msdb database is not granted access to SQL Agent proxies. + + Local Windows groups should not be used as logins for SQL Server instances. + + Allowing local Windows groups as SQL Logins provides a loophole whereby anyone with OS level administrator rights (and no SQL Server rights) could add users to the local + Windows groups and thereby give themselves or others access to the SQL Server instance. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("3.11") + $obj | Add-Member NoteProperty Task("Ensure the public role in the msdb database is not granted access to SQL Agent proxies") + + $query = "USE [msdb] + GO + SELECT sp.name AS proxyname + FROM dbo.sysproxylogin spl + JOIN sys.database_principals dp + ON dp.sid = spl.sid + JOIN sysproxies sp + ON sp.proxy_id = spl.proxy_id + WHERE principal_id = USER_ID('public'); + GO" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Found:" + $sqlResult.proxyname) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} +#endregion + +#region 4 Password Policies +# +# This section contains recommendations related to SQL Server's password policies. +# + +function Test-SQLMustChangeOptionIsOn { + <# +.Synopsis + Ensure the public role in the msdb database is not granted access to SQL Agent proxies. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 4 Password Policies + + 4.1 - Ensure 'MUST_CHANGE' Option is set to 'ON' for All SQL Authenticated Logins. + + Whenever this option is set to ON, SQL Server will prompt for an updated password the first time the new or altered login is used. + + Enforcing a password change after a reset or new login creation will prevent the account administrators or anyone accessing the initial password from misuse of the SQL login created without being noticed. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("4.1") + $obj | Add-Member NoteProperty Task("Ensure 'MUST_CHANGE' Option is set to 'ON' for All SQL Authenticated Logins") + + $query = "SELECT name, create_date + FROM sys.sql_logins" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlLogins = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlLogins = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + $mustChangeLogins = @() + foreach ($sqlLogin in $sqlLogins) { + $loginName = $sqlLogin.name + $query2 = "SELECT LOGINPROPERTY('$loginName', 'PasswordLastSetTime') AS 'PasswordLastSetTime'" + + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $SqlInstance -ne "MSSQLSERVER") { + $loginProperty = Invoke-Sqlcmd -Query $query2 -ServerInstance $instanceName -ErrorAction Stop + } + else { + $loginProperty = Invoke-Sqlcmd -Query $query2 -ServerInstance $MachineName -ErrorAction Stop + } + + if ((Get-Date $sqlLogin.create_date) -gt (Get-Date $loginProperty.PasswordLastSetTime)) { + $mustChangeLogins += $sqlLogin + } + } + if ($mustChangeLogins.Count -gt 0) { + $obj | Add-Member NoteProperty Status("Following Logins Must Change their password: " + $mustChangeLogins.name) + $obj | Add-Member NoteProperty Audit("False") + + } + else { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + + Write-Output $obj +} + +function Test-SQLCheckExpirationOptionOn { + <# +.Synopsis + Ensure the public role in the msdb database is not granted access to SQL Agent proxies. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 4 Password Policies + + 4.2 - Ensure 'CHECK_EXPIRATION' Option is set to 'ON' for All SQL Authenticated Logins Within the Sysadmin Role. + + Applies the same password expiration policy used in Windows to passwords used inside SQL Server. + + Ensuring SQL logins comply with the secure password policy applied by the Windows Server Benchmark will ensure the passwords for SQL logins with sysadmin privileges are + changed on a frequent basis to help prevent compromise via a brute force attack. CONTROL SERVER is an equivalent permission to sysadmin and logins with that permission should + also be required to have expiring passwords. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("4.2") + $obj | Add-Member NoteProperty Task("Ensure 'CHECK_EXPIRATION' Option is set to 'ON' for All SQL Authenticated Logins Within the Sysadmin Role") + + $query = "SELECT l.[name], 'sysadmin membership' AS 'Access_Method' + FROM sys.sql_logins AS l + WHERE IS_SRVROLEMEMBER('sysadmin',name) = 1 + AND l.is_expiration_checked <> 1 + UNION ALL + SELECT l.[name], 'CONTROL SERVER' AS 'Access_Method' + FROM sys.sql_logins AS l + JOIN sys.server_permissions AS p + ON l.principal_id = p.grantee_principal_id + WHERE p.type = 'CL' AND p.state IN ('G', 'W') + AND l.is_expiration_checked <> 1;" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + [string]$s = $null + $s = $sqlResult -join ", " + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Found missmatching account(s): " + $s.name) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLCheckPolicyOptionOn { + <# +.Synopsis + Ensure 'CHECK_POLICY' Option is set to 'ON' for All SQL Authenticated Logins. +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 4 Password Policies + + 4.3 - Ensure 'CHECK_POLICY' Option is set to 'ON' for All SQL Authenticated Logins. + + Applies the same password complexity policy used in Windows to passwords used inside SQL Server. + + Ensure SQL authenticated login passwords comply with the secure password policy applied by the Windows Server Benchmark so that they cannot be easily compromised via brute + force attack. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("4.3") + $obj | Add-Member NoteProperty Task("Ensure 'CHECK_POLICY' Option is set to 'ON' for All SQL Authenticated Logins") + + $query = "SELECT name, is_disabled + FROM sys.sql_logins + WHERE is_policy_checked = 0;" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Found missmatching account(s):" + $sqlResult.name) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} +#endregion + +#region 5 Auditing and Logging +# +#This section contains recommendations related to SQL Server's audit and logging mechanisms. +# + +function Test-SQLMaximumNumberOfErrorLogFiles { + <# + .Synopsis + Ensure 'Maximum number of error log files' is set to greater than or equal to '12' + .DESCRIPTION + CIS SQL Server 2016 Benchmark - 5 Auditing and Logging + + 5.1 Ensure 'Maximum number of error log files' is set to greater than or equal to '12' + + SQL Server error log files must be protected from loss. The log files must be backed up before they are overwritten. Retaining more error logs helps prevent loss from frequent recycling before backups can occur. + + The SQL Server error log contains important information about major server events and login attempt information as well. + #> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("5.1") + $obj | Add-Member NoteProperty Task("Ensure 'Maximum number of error log files' is set to greater than or equal to '12'") + + $query = "DECLARE @NumErrorLogs int; + EXEC master.sys.xp_instance_regread + N'HKEY_LOCAL_MACHINE', + N'Software\Microsoft\MSSQLServer\MSSQLServer', + N'NumErrorLogs', @NumErrorLogs OUTPUT; + SELECT ISNULL(@NumErrorLogs, -1) AS [NumberOfLogFiles];" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + $numberOfLogFiles = $sqlResult.NumberOfLogFiles + + if ($numberOfLogFiles -ge 12) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Maximum number of error log files is set to $numberOfLogFiles") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLDefaultTraceEnabled { + <# + .Synopsis + Ensure 'Default Trace Enabled' Server Configuration Option is set to '1' + .DESCRIPTION + CIS SQL Server 2016 Benchmark - 5 Auditing and Logging + + 5.2 Ensure 'Default Trace Enabled' Server Configuration Option is set to '1' + + The default trace provides audit logging of database activity including account creations, privilege elevation and execution of DBCC commands. + + Default trace provides valuable audit information regarding security-related activities on the server. + #> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("5.2") + $obj | Add-Member NoteProperty Task("Ensure 'Default Trace Enabled' Server Configuration Option is set to '1'") + + $query = "SELECT name, CAST(value as int) as value_configured, CAST(value_in_use as int) as value_in_use + FROM sys.configurations + WHERE name = 'default trace enabled';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if (($sqlResult.value_configured -eq 1) -and ($sqlResult.value_in_use -eq 1)) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Maximum number of error log files too high") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLLoginAuditingIsSetToFailedLogins { + <# + .Synopsis + Ensure 'Login Auditing' is set to 'failed logins' + .DESCRIPTION + CIS SQL Server 2016 Benchmark - 5 Auditing and Logging + + 5.3 Ensure 'Login Auditing' is set to 'failed logins' + + This setting will record failed authentication attempts for SQL Server logins to the SQL Server Errorlog. This is the default setting for SQL Server. + Default trace provides valuable audit information regarding security-related activities on the server. + Historically, this setting has been available in all versions and editions of SQL Server. Prior to the availability of SQL Server Audit, this was the only provided mechanism for capturing logins (successful or failed). + + Capturing failed logins provides key information that can be used to detect\confirm password guessing attacks. Capturing successful login attempts can be used to confirm server access during forensic investigations, but using this audit level setting to also capture successful logins creates excessive noise in the SQL Server Errorlog which can hamper a DBA trying to troubleshoot problems. Elsewhere in this benchmark, we recommend using the newer lightweight SQL Server Audit feature to capture both successful and failed logins. + #> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("5.3") + $obj | Add-Member NoteProperty Task("Ensure 'Login Auditing' is set to 'failed logins'") + + $query = "EXEC xp_loginconfig 'audit level';" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ($sqlResult.config_value -eq "failure") { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("config_value is set to: " + $sqlResult.config_value) + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} + +function Test-SQLLoginAuditingIsSetToFailedAndSuccessfulLogins { + <# + .Synopsis + Ensure 'SQL Server Audit' is set to capture both 'failed' and 'successful logins' + .DESCRIPTION + CIS SQL Server 2016 Benchmark - 5 Auditing and Logging + + 5.4 Ensure 'SQL Server Audit' is set to capture both 'failed' and 'successful logins' + + SQL Server Audit is capable of capturing both failed and successful logins and writing them to one of three places: the application event log, the security event log, or the file system. We will use it to capture any login attempt to SQL Server, as well as any attempts to change audit policy. This will also serve to be a second source to record failed login attempts. + + By utilizing Audit instead of the traditional setting under the Security tab to capture successful logins, we reduce the noise in the ERRORLOG. This keeps it smaller and easier to read for DBAs who are attempting to troubleshoot issues with the SQL Server. Also, the Audit object can write to the security event log, though this requires operating system configuration. This gives an additional option for where to store login events, especially in conjunction with an SIEM. + #> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("5.4") + $obj | Add-Member NoteProperty Task("Ensure 'SQL Server Audit' is set to capture both 'failed' and 'successful logins'") + + $query = "SELECT + S.name AS 'Audit Name' + , CASE S.is_state_enabled + WHEN 1 THEN 'Y' + WHEN 0 THEN 'N' END AS 'Audit Enabled' + , S.type_desc AS 'Write Location' + , SA.name AS 'Audit Specification Name' + , CASE SA.is_state_enabled + WHEN 1 THEN 'Y' + WHEN 0 THEN 'N' END AS 'Audit Specification Enabled' + , SAD.audit_action_name + , SAD.audited_result + FROM sys.server_audit_specification_details AS SAD + JOIN sys.server_audit_specifications AS SA + ON SAD.server_specification_id = SA.server_specification_id + JOIN sys.server_audits AS S + ON SA.audit_guid = S.audit_guid + WHERE SAD.audit_action_id IN ('CNAU', 'LGFL', 'LGSD'); + GO" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResults = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResults = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + $auditSpecifications = @() + foreach ($sqlResult in $sqlResults) { + switch ($sqlResult.audit_action_name) { + "AUDIT_CHANGE_GROUP" { + $auditSpecifications += ($sqlResult) + } + "FAILED_LOGIN_GROUP" { + $auditSpecifications += ($sqlResult) + } + "SUCCESSFUL_LOGIN_GROUP" { + $auditSpecifications += ($sqlResult) + } + Default {} + } + } + $foundSpecifications = @() + foreach ($auditSpecification in $auditSpecifications) { + if ((($auditspecification | Select-Object -ExpandProperty "Audit Enabled") -ne "Y") -or ` + (($auditspecification | Select-Object -ExpandProperty "Audit Specification Enabled") -ne "Y") -or ` + ($auditspecification.audited_result -ne "SUCCESS AND FAILURE")) { + $foundSPecifications += $auditSpecification.audit_action_name + } + } + if ($null -eq $sqlResult) { + $obj | Add-Member NoteProperty Status("TrackLogins file not found") + $obj | Add-Member NoteProperty Audit("Warning") + } + else { + if ($foundSpecifications.count -eq 0) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + [string]$s = $null + $s = $foundSpecifications -join ", " + $obj | Add-Member NoteProperty Status("Found following specifications: $s") + $obj | Add-Member NoteProperty Audit("False") + } + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + + Write-Output $obj +} +#endregion + +#region 6 Application Development +# +# This section contains recommendations related to developing applications that interface with SQL Server. +# +function Test-CLRAssemblyPermissionSet { + <# +.Synopsis + Ensure 'CLR Assembly Permission Set' is set to 'SAFE_ACCESS' for All CLR Assemblies +.DESCRIPTION + CIS SQL Server 2016 Benchmark - 6 Application Development + + 6.2 - Ensure 'CLR Assembly Permission Set' is set to 'SAFE_ACCESS' for All CLR Assemblies. + + Setting CLR Assembly Permission Sets to SAFE_ACCESS will prevent assemblies from accessing external system resources such as files, the network, environment variables, or the registry. + + Assemblies with EXTERNAL_ACCESS or UNSAFE permission sets can be used to access sensitive areas of the operating system, steal and/or transmit data and alter the state and other protection measures of the underlying Windows Operating System. Assemblies which are Microsoft-created (is_user_defined = 0) are excluded from this check as they are required for overall system functionality. +#> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("6.2") + $obj | Add-Member NoteProperty Task("Ensure 'CLR Assembly Permission Set' is set to 'SAFE_ACCESS' for All CLR Assemblies") + + $query = "SELECT name, + permission_set_desc + FROM sys.assemblies + where is_user_defined = 1;" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $assemblies = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $assemblies = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + $unSafeAssemblies = @() + foreach ($assembly in $assemblies) { + if ($assembly.permission_set_desc -ne "SAFE_ACCESS") { + $unSafeAssemblies += $assembly + } + } + if ($unSafeAssemblies.Count -gt 0 ) { + $obj | Add-Member NoteProperty Status("Found unsafe assmblies: " + $unSafeAssemblies) + $obj | Add-Member NoteProperty Audit("False") + } + else { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + + Write-Output $obj +} +#endregion + +#region 7 Encryption +# +# These recommendations pertain to encryption-related aspects of SQL Server. +# +function Test-SQLSymmetricKeyEncryptionAlgorithm { + <# + .Synopsis + Ensure 'Symmetric Key encryption algorithm' is set to 'AES_128' or higher in non-system databases + .DESCRIPTION + CIS SQL Server 2016 Benchmark - 7 Encryption + + 7.1 Ensure 'Symmetric Key encryption algorithm' is set to 'AES_128' or higher in non-system databases + + Per the Microsoft Best Practices, only the SQL Server AES algorithm options, AES_128, AES_192, and AES_256, should be used for a symmetric key encryption algorithm. + + The following algorithms (as referred to by SQL Server) are considered weak or deprecated and should no longer be used in SQL Server: DES, DESX, RC2, RC4, RC4_128. + Many organizations may accept the Triple DES algorithms (TDEA) which use keying options 1 (3 key aka 3TDEA) or keying option 2 (2 key aka 2TDEA). In SQL Server, these are referred to as TRIPLE_DES_3KEY and TRIPLE_DES respectively. Additionally, the SQL Server algorithm named DESX is actually the same implementation as the TRIPLE_DES_3KEY option. However, using the DESX identifier as the algorithm type has been deprecated and its usage is now discouraged. + #> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $databases = Get-SqlDatabase -ServerInstance $InstanceName -ErrorAction Stop | Where-Object {$_.IsSystemObject -ne "true"} | Select-Object -ExpandProperty name + } + else { + $databases = Get-SqlDatabase -ServerInstance $MachineName -ErrorAction Stop | Where-Object {$_.IsSystemObject -ne "true"} | Select-Object -ExpandProperty name + } + + if ($databases.Count -eq 0) { + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("7.1") + $obj | Add-Member NoteProperty Task("Ensure 'Symmetric Key encryption algorithm' is set to 'AES_128' or higher in non-system databases") + $obj | Add-Member NoteProperty Status("No databases found") + $obj | Add-Member NoteProperty Audit("True") + return $obj + } + $index = 1 + + foreach ($database in $databases) { + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("7.1.$index") + $obj | Add-Member NoteProperty Task("Ensure 'Symmetric Key encryption algorithm' is set to 'AES_128' or higher for database $database") + + + $query = "USE [$database] + GO + SELECT db_name() AS db_name, name AS Key_Name + FROM sys.symmetric_keys + WHERE algorithm_desc NOT IN ('AES_128','AES_192','AES_256') + AND db_id() > 4; + GO" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Got $sqlResult") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + + + Write-Output $obj + + $index++ + } + } + catch { + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("7.1") + $obj | Add-Member NoteProperty Task("Ensure 'Symmetric Key encryption algorithm' is set to 'AES_128' or higher in non-system databases") + $obj | Add-Member NoteProperty Status("Failed to connect to server $instanceName") + $obj | Add-Member NoteProperty Audit("Warning") + Write-Output $obj + } +} + +function Test-SQLAsymmetricKeySize { + <# + .Synopsis + Ensure Asymmetric Key Size is set to 'greater than or equal to 2048' in non-system databases + .DESCRIPTION + CIS SQL Server 2016 Benchmark - 7 Encryption + + 7.2 Ensure Asymmetric Key Size is set to 'greater than or equal to 2048' in non-system databases + + Microsoft Best Practices recommend to use at least a 2048-bit encryption algorithm for asymmetric keys. + + The RSA_2048 encryption algorithm for asymmetric keys in SQL Server is the highest bitlevel provided and therefore the most secure available choice (other choices are RSA_512 and RSA_1024). + #> + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME, + + [string] $InstanceName = "$machineName\$sqlInstance" + ) + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $databases = Get-SqlDatabase -ServerInstance $InstanceName -ErrorAction Stop | Where-Object {$_.IsSystemObject -ne "true"} | Select-Object -ExpandProperty name + } + else { + $databases = Get-SqlDatabase -ServerInstance $MachineName -ErrorAction Stop | Where-Object {$_.IsSystemObject -ne "true"} | Select-Object -ExpandProperty name + } + + if ($databases.Count -eq 0) { + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("7.2") + $obj | Add-Member NoteProperty Task("Ensure Asymmetric Key Size is set to 'greater than or equal to 2048' in non-system databases") + $obj | Add-Member NoteProperty Status("No databases found") + $obj | Add-Member NoteProperty Audit("True") + return $obj + } + + $index = 1 + + foreach ($database in $databases) { + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("7.2.$index") + $obj | Add-Member NoteProperty Task("Ensure CONNECT permissions on the 'guest' user is revoked for database $database") + + $query = "USE [$database] + GO + SELECT db_name() AS db_name, name AS Key_Name + FROM sys.symmetric_keys + WHERE key_length < 2048 + AND db_id() > 4; + GO" + + try { + if ($PsCmdlet.ParameterSetName -eq "ByInstance" -and $sqlInstance -ne "MSSQLSERVER") { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $instanceName -ErrorAction Stop + } + else { + $sqlResult = Invoke-Sqlcmd -Query $query -ServerInstance $MachineName -ErrorAction Stop + } + if ( $null -eq $sqlResult ) { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("Got $sqlResult") + $obj | Add-Member NoteProperty Audit("False") + } + } + catch [System.Data.SqlClient.SqlException] { + $obj | Add-Member NoteProperty Status("Server Instance not found or accessible") + $obj | Add-Member NoteProperty Audit("Warning") + } + + + Write-Output $obj + + $index++ + } + + } + catch { + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("7.2") + $obj | Add-Member NoteProperty Task("Ensure Asymmetric Key Size is set to 'greater than or equal to 2048' in non-system databases") + $obj | Add-Member NoteProperty Status("Failed to connect to server $instanceName") + $obj | Add-Member NoteProperty Audit("Warning") + Write-Output $obj + } +} + +#endregion + +#region 8 Appendix: Additional Considerations +# +# This appendix discusses possible configuration options for which no recommendation is being given. +# +function Test-SQLServerBrowserService { + <# + .Synopsis + Ensure 'SQL Server Browser Service' is configured correctly + .DESCRIPTION + CIS SQL Server 2016 Benchmark - 8 Appendix: Additional Considerations + + 8.1 Ensure 'SQL Server Browser Service' is configured correctly + + No recommendation is being given on disabling the SQL Server Browser service. + #> + [CmdletBinding()] + + $obj = New-Object PSObject + $obj | Add-Member NoteProperty ID("8.1") + $obj | Add-Member NoteProperty Task("Ensure 'SQL Server Browser Service' is configured correctly") + + try { + $sqlBrowserService = Get-Service -name 'sqlbrowser' + + if ($sqlBrowserService.Status -eq 'stopped') { + if ($sqlBrowserService.StartType -eq 'Disabled') { + $obj | Add-Member NoteProperty Status("All good") + $obj | Add-Member NoteProperty Audit("True") + } + else { + $obj | Add-Member NoteProperty Status("StartType: Enabled") + $obj | Add-Member NoteProperty Audit("Warning") + } + } + else { + $obj | Add-Member NoteProperty Audit("False") + if ($sqlBrowserService.StartType -eq 'Disabled') { + $obj | Add-Member NoteProperty Status("SQL Server Browser is running") + } + else { + $obj | Add-Member NoteProperty Status("SQL Server Browser is running and StartType: Enabled") + } + } + } + catch [Microsoft.PowerShell.Commands.ServiceCommandException] { + $obj | Add-Member NoteProperty Status("Connot find any service with service name 'sqlbrowser'") + $obj | Add-Member NoteProperty Audit("Warning") + } + Write-Output $obj +} +#endregion + +#region Hyperfunctions +function Convert-ToAuditInfo { + param ( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [Psobject] $auditObject + ) + + process { + Write-Output @{ + Id = $auditObject.ID + Task = $auditObject.Task + Message = $auditObject.Status + Status = $auditObject.Audit + } + } +} +#endregion + +#region Reportgeneration +function Get-SQL2016AuditInfos { + [CmdletBinding(DefaultParameterSetName = "Default")] + param( + [Parameter(Mandatory = $true, ParameterSetName = "ByInstance")] + [string] $SqlInstance, + + [string] $MachineName = $env:COMPUTERNAME + ) + + switch ($PsCmdlet.ParameterSetName) { + "ByInstance" { + $sqlInstances = $sqlInstance + break + } + "Default" { + $smo = 'Microsoft.SqlServer.Management.Smo.' + $wmi = New-Object ($smo + 'Wmi.ManagedComputer') + $singleWmi = $wmi | Where-Object { $_.Name -eq $machineName } + $sqlServer = $singleWmi.Services | Where-Object { $_.Type -eq "SqlServer" } + $sqlInstances = $sqlServer ` + | Foreach-Object { $_.Name.Substring($_.Name.IndexOf('$') + 1) } ` + # | Where-Object { $_ -ne "MSSQLSERVER" } + } + } + + $InstanceAudits = @() + foreach ($sqlInstance in $sqlInstances) { + $auditInfos = @() + + # Section 2 + $auditInfos += Test-SQLAdHocDistributedQueriesDisabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLClrEnabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLCrossDBOwnershipDisabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLDatabaseMailXPsDisabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLOleAutomationProceduresDisabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLRemoteAccessDisabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLRemoteAdminConnectionsDisabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLScanForStartupProcsDisabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLTrustworthyDatabaseOff -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLServerProtocolsDisabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLUseNonStandardPorts -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLHideInstanceEnabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLSaLoginAccountDisabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLSaLoginAccountRenamed -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLXpCommandShellDisabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLAutoCloseOff -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLNoSaAccounnt -MachineName $machineName -SqlInstance $sqlInstance + + # Section 3 + $auditInfos += Test-SQLServerAuthentication -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLGuestPermissionOnDatabases -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLDropOrphanedUsers -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLAuthenticationDisabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLServerServiceAccountIsNotAnAdministrator -MachineName $machineName + $auditInfos += Test-SQLAgentServiceAccountIsNotAnAdministrator -MachineName $machineName + $auditInfos += Test-SQLFullTextServiceAccountIsNotAnAdministrator -MachineName $machineName + $auditInfos += Test-SQLPermissionsForRolePublic -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLWindowsBuiltinNoSqlLogin -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLWindowsLocalGroupsNoSqlLogin -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLPublicRoleMsdbDatabase -MachineName $machineName -SqlInstance $sqlInstance + + # Section 4 + $auditInfos += Test-SQLMustChangeOptionIsOn -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLCheckExpirationOptionOn -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLCheckPolicyOptionOn -MachineName $machineName -SqlInstance $sqlInstance + + # Section 5 + $auditInfos += Test-SQLMaximumNumberOfErrorLogFiles -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLDefaultTraceEnabled -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLLoginAuditingIsSetToFailedLogins -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLLoginAuditingIsSetToFailedAndSuccessfulLogins -MachineName $machineName -SqlInstance $sqlInstance + + # Section 6 + $auditInfos += Test-CLRAssemblyPermissionSet -MachineName $machineName -SqlInstance $sqlInstance + + # Section 7 + $auditInfos += Test-SQLSymmetricKeyEncryptionAlgorithm -MachineName $machineName -SqlInstance $sqlInstance + $auditInfos += Test-SQLAsymmetricKeySize -MachineName $machineName -SqlInstance $sqlInstance + + # Section 8 + $auditInfos += Test-SQLServerBrowserService + + $InstanceAudits += @{ + InstanceName = $sqlInstance + AuditInfos = $auditInfos | Convert-ToAuditInfo + } + } + + return $InstanceAudits +} + +switch ($PsCmdlet.ParameterSetName) { + "ByInstance" { + $InstanceAudits = (Get-SQL2016AuditInfos -SqlInstance $sqlInstance -MachineName $machineName) + break + } + "ByAuditInfo" { + break + } + "Default" { + $InstanceAudits = (Get-SQL2016AuditInfos) + } +} + +[Report] @{ + Title = "SQL 2016 Benchmarks" + ModuleName = "ATAPAuditor" + BasedOn = "CIS Microsoft SQL Server 2016 Benchmark, Version: 1.0.0, Date: 2017-11-08" + Sections = @( + foreach ($InstanceAudit in $InstanceAudits) { + [ReportSection] @{ + Title = $InstanceAudit.InstanceName + Description = "This section contains the audits for the sqlInstance $($InstanceAudit.InstanceName)" + SubSections = @( + [ReportSection] @{ + Title = "2 Surface Area Reduction" + Description = "SQL Server offers various configuration options, some of them can be controlled by the sp_configure stored procedure. This section contains the listing of the corresponding recommendations." + AuditInfos = $InstanceAudit.AuditInfos | Where-Object {$_.Id -like "2.*"} + } + [ReportSection] @{ + Title = "3 Authentication and Authorization" + Description = "This section contains recommendations related to SQL Server's authentication and authorization mechanisms." + AuditInfos = $InstanceAudit.AuditInfos | Where-Object {$_.Id -like "3.*"} + } + [ReportSection] @{ + Title = "4 Password Policies" + Description = "This section contains recommendations related to SQL Server's password policies." + AuditInfos = $InstanceAudit.AuditInfos | Where-Object {$_.Id -like "4.*"} + } + [ReportSection] @{ + Title = "5 Auditing and Logging" + Description = "This section contains recommendations related to SQL Server's audit and logging mechanisms." + AuditInfos = $InstanceAudit.AuditInfos | Where-Object {$_.Id -like "5.*"} + } + [ReportSection] @{ + Title = "6 Application Development" + Description = "This section contains recommendations related to developing applications that interface with SQL Server." + AuditInfos = $InstanceAudit.AuditInfos | Where-Object {$_.Id -like "6.*"} + } + [ReportSection] @{ + Title = "7 Encryption" + Description = "These recommendations pertain to encryption-related aspects of SQL Server." + AuditInfos = $InstanceAudit.AuditInfos | Where-Object {$_.Id -like "7.*"} + } + [ReportSection] @{ + Title = "8 Appendix: Additional Considerations" + Description = "This appendix discusses possible configuration options for which no recommendation is being given." + AuditInfos = $InstanceAudit.AuditInfos | Where-Object {$_.Id -like "8.*"} + } + ) + } + } + ) +} +#endregion diff --git a/ATAPAuditor/Reports/Microsoft Windows 10 BSI.ps1 b/ATAPAuditor/Reports/Microsoft Windows 10 BSI.ps1 new file mode 100644 index 0000000..a83242e --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Windows 10 BSI.ps1 @@ -0,0 +1,114 @@ +[Report] @{ + Title = "Windows 10 BSI Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "BSI Configuration Recommendations for Hardening of Windows 10 Using Built-in Functionalities: Version 1.3, Date: 2021-05-03" + "BSI SiSyPHuS Recommendations for Telemetry Components: Version 1.2, Date: 2020-04-27" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.2.1, Date: 2023-11-03" + "FB Pro recommendations 'Enhanced settings', Version 1.2.1, Date: 2023-11-03" + ) + Sections = @( + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHuS Logging' + Description = "This section contains all BSI logging recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#RegistrySettings" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#AuditPolicies" + } + ) + } + try { + # Get domain role + # 0 {"Standalone Workstation"} + # 1 {"Member Workstation"} + # 2 {"Standalone Server"} + # 3 {"Member Server"} + # 4 {"Backup Domain Controller"} + # 5 {"Primary Domain Controller"} + $domainRole = (Get-CimInstance -Class Win32_ComputerSystem).DomainRole + } catch { + $domainRole = 99 + } + # if system is Member Workstation + if ($domainRole -eq 1) { + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHuS HD' + Description = "This section contains all BSI HD recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#RegistrySettings" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#UserRights" + } + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#AccountPolicies" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#SecurityOptions" + } + ) + } + } else { + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHuS NE' + Description = "This section contains all BSI NE recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#RegistrySettings" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#UserRights" + } + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#AccountPolicies" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#SecurityOptions" + } + ) + } + } + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHus-BSI Telemetrie' + Description = "This section contains all BSI telemetry recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHus-Telemetrie-BSI-V1.2#RegistrySettings" + } + ) + } + [ReportSection] @{ + Title = 'FB Pro recommendations' + Description = "This section contains all FB Pro recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Ciphers Suites and Hashes' + AuditInfos = Test-AuditGroup "CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - Registry Settings' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - User Rights' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft Windows 10 GDPR.ps1 b/ATAPAuditor/Reports/Microsoft Windows 10 GDPR.ps1 new file mode 100644 index 0000000..223b19f --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Windows 10 GDPR.ps1 @@ -0,0 +1,50 @@ +[Report] @{ + Title = "Windows 10 GDPR Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + 'Bundesamt für Sicherheit in der Informationstechnik (BSI), Version: V1.2, Date: 2020-04-27' + 'GDPR settings by Microsoft, Version: 16082019, Date: 2019-08-16' + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.2.1, Date: 2023-11-03" + "FB Pro recommendations 'Enhanced settings', Version 1.2.1, Date: 2023-11-03" + ) + Sections = @( + [ReportSection] @{ + Title = "BSI Recommendations" + Description = "This section contains the Telemetry-Recommendations of the Federal Office for Information Security (BSI)" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings" + AuditInfos = Test-AuditGroup "Microsoft Windows 10 GDPR-MS-16082019#RegistrySettings" + } + ) + } + [ReportSection] @{ + Title = "Data Protection Microsoft" + Description = "This section contains all Microsoft recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Telemetry" + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHus-Telemetrie-BSI-V1.2#RegistrySettings" + } + ) + } + [ReportSection] @{ + Title = 'FB Pro recommendations' + Description = "This section contains all FB Pro recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Ciphers Suites and Hashes' + AuditInfos = Test-AuditGroup "CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - Registry Settings' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - User Rights' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft Windows 10 Stand-alone.ps1 b/ATAPAuditor/Reports/Microsoft Windows 10 Stand-alone.ps1 new file mode 100644 index 0000000..c0cf77d --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Windows 10 Stand-alone.ps1 @@ -0,0 +1,103 @@ +[Report] @{ + Title = "Windows 10 Stand-alone Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Microsoft Windows 10 Stand-alone Benchmark, Version: 2.0.0, Date: 2023-05-17" + "BSI Configuration Recommendations for Hardening of Windows 10 Using Built-in Functionalities: Version 1.3, Date: 2021-05-03" + "BSI SiSyPHuS Recommendations for Telemetry Components: Version 1.2, Date: 2020-04-27" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.2.1, Date: 2023-11-03" + "FB Pro recommendations 'Enhanced settings', Version 1.2.1, Date: 2023-11-03" + ) + Sections = @( + [ReportSection] @{ + Title = 'CIS Stand-alone Benchmarks' + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-Stand-alone-CIS-2.0.0#AccountPolicies" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-Stand-alone-CIS-2.0.0#AuditPolicies" + } + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-Stand-alone-CIS-2.0.0#RegistrySettings" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-Stand-alone-CIS-2.0.0#SecurityOptions" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-Stand-alone-CIS-2.0.0#UserRights" + } + ) + } + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHuS Logging' + Description = 'This section contains the BSI Benchmark results.' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#RegistrySettings" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#AuditPolicies" + } + ) + } + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHus-BSI Telemetrie' + Description = 'This section contains the BSI Benchmark results.' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHus-Telemetrie-BSI-V1.2#RegistrySettings" + } + ) + } + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHuS NE' + Description = 'This section contains the BSI Benchmark results.' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#RegistrySettings" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#UserRights" + } + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#AccountPolicies" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#SecurityOptions" + } + ) + } + [ReportSection] @{ + Title = 'FB Pro recommendations' + Description = "This section contains all FB Pro recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Ciphers Suites and Hashes' + AuditInfos = Test-AuditGroup "CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - Registry Settings' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - User Rights' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft Windows 10.ps1 b/ATAPAuditor/Reports/Microsoft Windows 10.ps1 new file mode 100644 index 0000000..65f9cfd --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Windows 10.ps1 @@ -0,0 +1,199 @@ +[Report] @{ + Title = "Windows 10 Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Microsoft Windows 10 Enterprise, Version: 3.0.0, Date: 2024-02-22" + "Microsoft Security baseline (FINAL) for Windows 10, Version: 21H1, Date: 2021-05-18" + "BSI Configuration Recommendations for Hardening of Windows 10 Using Built-in Functionalities: Version 1.3, Date: 2021-05-03" + "BSI SiSyPHuS Recommendations for Telemetry Components: Version 1.2, Date: 2020-04-27" + "DISA Windows 10 Security Technical Implementation Guide, Version: V1R23, Date: 2019-10-25" + "ACSC Hardening Microsoft Windows 10 version 21H1 Workstations, Version: 10.2021, Date 2021-10-01" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.2.1, Date: 2023-11-03" + "FB Pro recommendations 'Enhanced settings', Version 1.2.1, Date: 2023-11-03" + ) + Sections = @( + [ReportSection] @{ + Title = 'CIS Benchmarks' + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-CIS-3.0.0#RegistrySettings" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-CIS-3.0.0#UserRights" + } + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-CIS-3.0.0#AccountPolicies" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-CIS-3.0.0#AuditPolicies" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-CIS-3.0.0#SecurityOptions" + } + ) + } + [ReportSection] @{ + Title = 'Microsoft Benchmarks' + Description = "This section contains all Microsoft recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-Microsoft-21H1#RegistrySettings" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-Microsoft-21H1#UserRights" + } + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-Microsoft-21H1#AccountPolicies" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-Microsoft-21H1#AuditPolicies" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-Microsoft-21H1#SecurityOptions" + } + ) + } + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHuS Logging' + Description = 'This section contains all BSI logging recommendations' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#RegistrySettings" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#AuditPolicies" + } + ) + } + try { + # Get domain role + # 0 {"Standalone Workstation"} + # 1 {"Member Workstation"} + # 2 {"Standalone Server"} + # 3 {"Member Server"} + # 4 {"Backup Domain Controller"} + # 5 {"Primary Domain Controller"} + $domainRole = (Get-CimInstance -Class Win32_ComputerSystem).DomainRole + } catch { + $domainRole = 99 + } + # if system is Member Workstation + if ($domainRole -eq 1) { + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHuS HD' + Description = 'This section contains all BSI HD recommendations' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#RegistrySettings" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#UserRights" + } + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#AccountPolicies" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#SecurityOptions" + } + ) + } + } + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHus-BSI Telemetrie' + Description = 'This section contains all BSI telemetry recommendations' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHus-Telemetrie-BSI-V1.2#RegistrySettings" + } + ) + } + [ReportSection] @{ + Title = "DISA Recommendations" + Description = "This section contains all DISA recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows 10-DISA-V1R23#RegistrySettings" + } + [ReportSection] @{ + Title = "User Rights Assignment" + AuditInfos = Test-AuditGroup "Microsoft Windows 10-DISA-V1R23#UserRights" + } + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows 10-DISA-V1R23#AccountPolicies" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-DISA-V1R23#AuditPolicies" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-DISA-V1R23#SecurityOptions" + } + ) + } + [ReportSection] @{ + Title = 'ACSC Benchmarks' + Description = "This section contains all ACSC recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-ACSC-21H1#AccountPolicies" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-ACSC-21H1#AuditPolicies" + } + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-ACSC-21H1#RegistrySettings" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-ACSC-21H1#SecurityOptions" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 10-ACSC-21H1#UserRights" + } + ) + } + [ReportSection] @{ + Title = 'FB Pro recommendations' + Description = "This section contains all FB Pro recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Ciphers Suites and Hashes' + AuditInfos = Test-AuditGroup "CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - Registry Settings' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - User Rights' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft Windows 11 Stand-alone.ps1 b/ATAPAuditor/Reports/Microsoft Windows 11 Stand-alone.ps1 new file mode 100644 index 0000000..c2f0a14 --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Windows 11 Stand-alone.ps1 @@ -0,0 +1,103 @@ +[Report] @{ + Title = "Windows 11 Stand-alone Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 2.0.0, Date: 2023-05-04" + "BSI Configuration Recommendations for Hardening of Windows 10 Using Built-in Functionalities: Version 1.3, Date: 2021-05-03" + "BSI SiSyPHuS Recommendations for Telemetry Components: Version 1.2, Date: 2019-07-31" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.2.1, Date: 2023-11-03" + "FB Pro recommendations 'Enhanced settings', Version 1.2.1, Date: 2023-11-03" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Stand-alone Benchmarks" + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-Stand-alone-CIS-2.0.0#AccountPolicies" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-Stand-alone-CIS-2.0.0#AuditPolicies" + } + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-Stand-alone-CIS-2.0.0#RegistrySettings" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-Stand-alone-CIS-2.0.0#SecurityOptions" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-Stand-alone-CIS-2.0.0#UserRights" + } + ) + } + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHuS Logging' + Description = 'This section contains all BSI logging recommendations' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#RegistrySettings" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#AuditPolicies" + } + ) + } + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHus-BSI' + Description = 'This section contains all BSI telemetry recommendations' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHus-Telemetrie-BSI-V1.2#RegistrySettings" + } + ) + } + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHuS NE' + Description = 'This section contains all BSI NE recommendations' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#RegistrySettings" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#UserRights" + } + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#AccountPolicies" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#SecurityOptions" + } + ) + } + [ReportSection] @{ + Title = 'FB Pro recommendations' + Description = "This section contains all FB Pro recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Ciphers Suites and Hashes' + AuditInfos = Test-AuditGroup "CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - Registry Settings' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - User Rights' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights" + } + ) + } + ) +} \ No newline at end of file diff --git a/ATAPAuditor/Reports/Microsoft Windows 11.ps1 b/ATAPAuditor/Reports/Microsoft Windows 11.ps1 new file mode 100644 index 0000000..dad6094 --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Windows 11.ps1 @@ -0,0 +1,168 @@ +[Report] @{ + Title = "Windows 11 Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Microsoft Windows 11 Enterprise 4.0.0 Benchmark, Version: 4.0.0, Date: 2025-03-19" + "Microsoft Security baseline for Microsoft Windows 11, Version: 22H2, Date: 2022-09-20" + "BSI Configuration Recommendations for Hardening of Windows 10 Using Built-in Functionalities: Version 1.3, Date: 2021-05-03" + "BSI SiSyPHuS Recommendations for Telemetry Components: Version 1.2, Date: 2019-07-31" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.2.1, Date: 2023-11-03" + "FB Pro recommendations 'Enhanced settings', Version 1.2.1, Date: 2023-11-03" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-CIS-4.0.0#RegistrySettings" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-CIS-4.0.0#UserRights" + } + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-CIS-4.0.0#AccountPolicies" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-CIS-4.0.0#AuditPolicies" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-CIS-4.0.0#SecurityOptions" + } + ) + } + [ReportSection] @{ + Title = "Microsoft Benchmarks" + Description = "This section contains all Microsoft recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-Microsoft-22H2#RegistrySettings" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-Microsoft-22H2#UserRights" + } + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-Microsoft-22H2#AccountPolicies" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-Microsoft-22H2#AuditPolicies" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 11-Microsoft-22H2#SecurityOptions" + } + ) + } + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHuS Logging' + Description = 'This section contains all BSI logging recommendations' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#RegistrySettings" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS Logging-BSI-1.3#AuditPolicies" + } + ) + } + try { + # Get domain role + # 0 {"Standalone Workstation"} + # 1 {"Member Workstation"} + # 2 {"Standalone Server"} + # 3 {"Member Server"} + # 4 {"Backup Domain Controller"} + # 5 {"Primary Domain Controller"} + $domainRole = (Get-CimInstance -Class Win32_ComputerSystem).DomainRole + } catch { + $domainRole = 99 + } + # if system is Member Workstation + if ($domainRole -eq 1) { + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHuS HD' + Description = 'This section contains all BSI HD recommendations' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#RegistrySettings" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#UserRights" + } + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#AccountPolicies" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS HD-BSI-1.3#SecurityOptions" + } + ) + } + } else { + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHuS NE' + Description = 'This section contains all BSI NE recommendations' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#RegistrySettings" + } + [ReportSection] @{ + Title = 'User Rights Assignment' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#UserRights" + } + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#AccountPolicies" + } + [ReportSection] @{ + Title = 'Security Options' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHuS NE-BSI-1.3#SecurityOptions" + } + ) + } + } + [ReportSection] @{ + Title = 'BSI Benchmarks SiSyPHus-BSI' + Description = 'This section contains all BSI telemetry recommendations' + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 10 SiSyPHus-Telemetrie-BSI-V1.2#RegistrySettings" + } + ) + } + [ReportSection] @{ + Title = 'FB Pro recommendations' + Description = "This section contains all FB Pro recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Ciphers Suites and Hashes' + AuditInfos = Test-AuditGroup "CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - Registry Settings' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - User Rights' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft Windows 7.ps1 b/ATAPAuditor/Reports/Microsoft Windows 7.ps1 new file mode 100644 index 0000000..43a1bc9 --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Windows 7.ps1 @@ -0,0 +1,47 @@ +[Report] @{ + Title = "Windows 7 Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Microsoft Windows 7 Workstation Benchmark, Version: 3.1.0, Date: 2018-03-02" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.2.1, Date: 2023-11-03" + "FB Pro recommendations 'Enhanced settings', Version 1.2.1, Date: 2023-11-03" + ) + Sections = @( + [ReportSection] @{ + Title = 'CIS Benchmarks' + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Registry Settings/Group Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 7-CIS-3.1.0#RegistrySettings" + } + [ReportSection] @{ + Title = 'Account Policies' + AuditInfos = Test-AuditGroup "Microsoft Windows 7-CIS-3.1.0#AccountPolicies" + } + [ReportSection] @{ + Title = 'Advanced Audit Policy Configuration' + AuditInfos = Test-AuditGroup "Microsoft Windows 7-CIS-3.1.0#AuditPolicies" + } + ) + } + [ReportSection] @{ + Title = 'FB Pro recommendations' + Description = "This section contains all FB Pro recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Ciphers Suites and Hashes' + AuditInfos = Test-AuditGroup "CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - Registry Settings' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - User Rights' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft Windows Server 2012.ps1 b/ATAPAuditor/Reports/Microsoft Windows Server 2012.ps1 new file mode 100644 index 0000000..f05f961 --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Windows Server 2012.ps1 @@ -0,0 +1,76 @@ + +[Report] @{ + Title = "Windows Server 2012 Audit Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Microsoft Windows Server 2012 R2 Benchmark, Version: 3.0.0, Date: 2023-10-20", + "DISA Microsoft Windows Server 2012 R2 Benchmark, Version: V2R19, Date: 2020-07-17", + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.2.1, Date: 2023-11-03" + "FB Pro recommendations 'Enhanced settings', Version 1.2.1, Date: 2023-11-03" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2012 R2-CIS-3.0.0#RegistrySettings" + } + [ReportSection] @{ + Title = "User Rights Assignment" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2012 R2-CIS-3.0.0#UserRights" + } + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2012 R2-CIS-3.0.0#AccountPolicies" + } + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2012 R2-CIS-3.0.0#AuditPolicies" + } + [ReportSection] @{ + Title = "Security Options" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2012 R2-CIS-3.0.0#SecurityOptions" + } + ) + } + + [ReportSection] @{ + Title = "DISA Benchmarks" + Description = "This section contains all DISA recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2012 R2-DISA-V2R19#RegistrySettings" + } + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2012 R2-DISA-V2R19#AccountPolicies" + } + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2012 R2-DISA-V2R19#AuditPolicies" + } + ) + } + [ReportSection] @{ + Title = 'FB Pro recommendations' + Description = "This section contains all FB Pro recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Ciphers Suites and Hashes' + AuditInfos = Test-AuditGroup "CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - Registry Settings' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - User Rights' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft Windows Server 2016.ps1 b/ATAPAuditor/Reports/Microsoft Windows Server 2016.ps1 new file mode 100644 index 0000000..56f83e5 --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Windows Server 2016.ps1 @@ -0,0 +1,102 @@ + +[Report] @{ + Title = "Windows Server 2016 Audit Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Microsoft Windows Server 2016 Benchmark, Version: 3.0.0, Date: 2024-04-19" + "Microsoft Security baseline for Windows Server 2016, Version: FINAL, Date 2016-10-17" + "DISA Windows Server 2016 Security Technical Implementation Guide, Version: V1R12, Date: 2020-06-17" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.2.1, Date: 2023-11-03" + "FB Pro recommendations 'Enhanced settings', Version 1.2.1, Date: 2023-11-03" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-CIS-3.0.0#AccountPolicies" + } + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-CIS-3.0.0#AuditPolicies" + } + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-CIS-3.0.0#RegistrySettings" + } + [ReportSection] @{ + Title = "Security Options" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-CIS-3.0.0#SecurityOptions" + } + [ReportSection] @{ + Title = "User Rights Assignment" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-CIS-3.0.0#UserRights" + } + ) + } + [ReportSection] @{ + Title = "Microsoft Benchmarks" + Description = "This section contains all Microsoft recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-Microsoft-FINAL#RegistrySettings" + } + [ReportSection] @{ + Title = "User Rights Assignment" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-Microsoft-FINAL#UserRights" + } + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-Microsoft-FINAL#AccountPolicies" + } + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-Microsoft-FINAL#AuditPolicies" + } + ) + } + [ReportSection] @{ + Title = "DISA Recommendations" + Description = "This section contains all DISA recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-DISA-V1R12#AccountPolicies" + }, + [ReportSection] @{ + Title = "Security Options" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-DISA-V1R12#SecurityOptions" + }, + [ReportSection] @{ + Title = "Registry Permissions" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-DISA-V1R12#RegistrySettings" + }, + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2016-DISA-V1R12#AuditPolicies" + } + ) + } + [ReportSection] @{ + Title = 'FB Pro recommendations' + Description = "This section contains all FB Pro recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Ciphers Suites and Hashes' + AuditInfos = Test-AuditGroup "CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - Registry Settings' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - User Rights' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft Windows Server 2019.ps1 b/ATAPAuditor/Reports/Microsoft Windows Server 2019.ps1 new file mode 100644 index 0000000..e0b4f38 --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Windows Server 2019.ps1 @@ -0,0 +1,106 @@ + +[Report] @{ + Title = "Windows Server 2019 Audit Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Microsoft Windows Server 2019 Benchmark, Version: 3.0.0, Date: 2024-03-19" + "Microsoft Security baseline for Windows Server 2019, Version: FINAL, Date 2019-06-18" + "DISA Windows Server 2019 Security Technical Implementation Guide, Version: V1R5, Date: 2020-06-17" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.2.1, Date: 2023-11-03" + "FB Pro recommendations 'Enhanced settings', Version 1.2.1, Date: 2023-11-03" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-CIS-3.0.0#RegistrySettings" + } + [ReportSection] @{ + Title = "User Rights Assignment" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-CIS-3.0.0#UserRights" + } + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-CIS-3.0.0#AccountPolicies" + } + [ReportSection] @{ + Title = "Security Options" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-CIS-3.0.0#SecurityOptions" + } + [ReportSection] @{ + Title = " Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-CIS-3.0.0#AuditPolicies" + } + ) + } + [ReportSection] @{ + Title = "Microsoft Benchmarks" + Description = "This section contains all Microsoft recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-Microsoft-FINAL#RegistrySettings" + } + [ReportSection] @{ + Title = "User Rights Assignment" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-Microsoft-FINAL#UserRights" + } + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-Microsoft-FINAL#AccountPolicies" + } + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-Microsoft-FINAL#AuditPolicies" + } + [ReportSection] @{ + Title = "Security Options" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-Microsoft-FINAL#SecurityOptions" + } + ) + } + [ReportSection] @{ + Title = "DISA Recommendations" + Description = "This section contains all DISA recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-DISA-V1R5#RegistrySettings" + }, + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-DISA-V1R5#AccountPolicies" + }, + [ReportSection] @{ + Title = "Security Options" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-DISA-V1R5#SecurityOptions" + }, + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2019-DISA-V1R5#AuditPolicies" + } + ) + } + [ReportSection] @{ + Title = 'FB Pro recommendations' + Description = "This section contains all FB Pro recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Ciphers Suites and Hashes' + AuditInfos = Test-AuditGroup "CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - Registry Settings' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - User Rights' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft Windows Server 2022.ps1 b/ATAPAuditor/Reports/Microsoft Windows Server 2022.ps1 new file mode 100644 index 0000000..0d48f0e --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Windows Server 2022.ps1 @@ -0,0 +1,106 @@ + +[Report] @{ + Title = "Windows Server 2022 Audit Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Microsoft Windows Server 2022, Version: 3.0.0, Date 2023-04-14" + "Microsoft Security baseline for Microsoft Windows Server 2022, Version: FINAL, Date 2021-09-27" + "DISA Windows Server 2022, Version: V1R1, Date 2022-09-28" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.2.1, Date: 2023-11-03" + "FB Pro recommendations 'Enhanced settings', Version 1.2.1, Date: 2023-11-03" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-CIS-3.0.0#RegistrySettings" + } + [ReportSection] @{ + Title = "User Rights Assignment" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-CIS-3.0.0#UserRights" + } + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-CIS-3.0.0#AccountPolicies" + } + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-CIS-3.0.0#AuditPolicies" + } + [ReportSection] @{ + Title = "Security Options" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-CIS-3.0.0#SecurityOptions" + } + ) + } + [ReportSection] @{ + Title = "Microsoft Benchmarks" + Description = "This section contains all Microsoft recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-Microsoft-FINAL#RegistrySettings" + } + [ReportSection] @{ + Title = "User Rights Assignment" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-Microsoft-FINAL#UserRights" + } + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-Microsoft-FINAL#AccountPolicies" + } + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-Microsoft-FINAL#AuditPolicies" + } + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-Microsoft-FINAL#SecurityOptions" + } + ) + } + [ReportSection] @{ + Title = "DISA Benchmarks" + Description = "This section contains all DISA recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-DISA-V1R1#RegistrySettings" + } + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-DISA-V1R1#AccountPolicies" + } + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-DISA-V1R1#AuditPolicies" + } + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2022-DISA-V1R1#SecurityOptions" + } + ) + } + [ReportSection] @{ + Title = 'FB Pro recommendations' + Description = "This section contains all FB Pro recommendations" + SubSections = @( + [ReportSection] @{ + Title = 'Ciphers Suites and Hashes' + AuditInfos = Test-AuditGroup "CiphersProtocolsHashesBenchmark-FBPro-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - Registry Settings' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#RegistrySettings" + } + [ReportSection] @{ + Title = 'Enhanced security settings - User Rights' + AuditInfos = Test-AuditGroup "Microsoft Windows Enhanced Security Settings-FB Pro GmbH-1.2.1#UserRights" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Microsoft Windows Server 2025.ps1 b/ATAPAuditor/Reports/Microsoft Windows Server 2025.ps1 new file mode 100644 index 0000000..cfbdcfe --- /dev/null +++ b/ATAPAuditor/Reports/Microsoft Windows Server 2025.ps1 @@ -0,0 +1,38 @@ + +[Report] @{ + Title = "Windows Server 2025 Audit Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Microsoft Windows Server 2025, Version: 1.0.0, Date 2025-03-19" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.2.1, Date: 2023-11-03" + "FB Pro recommendations 'Enhanced settings', Version 1.2.1, Date: 2023-11-03" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains all CIS recommendations" + SubSections = @( + [ReportSection] @{ + Title = "Registry Settings/Group Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2025-CIS-1.0.0#RegistrySettings" + } + [ReportSection] @{ + Title = "User Rights Assignment" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2025-CIS-1.0.0#UserRights" + } + [ReportSection] @{ + Title = "Account Policies" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2025-CIS-1.0.0#AccountPolicies" + } + [ReportSection] @{ + Title = "Advanced Audit Policy Configuration" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2025-CIS-1.0.0#AuditPolicies" + } + [ReportSection] @{ + Title = "Security Options" + AuditInfos = Test-AuditGroup "Microsoft Windows Server 2025-CIS-1.0.0#SecurityOptions" + } + ) + } + ) +} \ No newline at end of file diff --git a/ATAPAuditor/Reports/Mozilla Firefox.ps1 b/ATAPAuditor/Reports/Mozilla Firefox.ps1 new file mode 100644 index 0000000..6cb74c6 --- /dev/null +++ b/ATAPAuditor/Reports/Mozilla Firefox.ps1 @@ -0,0 +1,873 @@ +<# +BSD 3-Clause License + +Copyright (c) 2023, FB Pro GmbH +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#> + +#region Import tests configuration settings +$CisBenchmarks = @{ + FirefoxLockPrefSettings = @( + @{ + Id = "2.1" + Task = "Enable Automatic Updates" + LockPrefs = @( + @{ Name = "app.update.auto"; Value = $true } + @{ Name = "app.update.enabled"; Value = $true } + @{ Name = "app.update.staging.enabled"; Value = $true } + ) + } + @{ + Id = "2.2" + Task = "Enable Auto-Notification of Outdated Plugins" + LockPrefs = @( + @{ Name = "plugins.update.notifyUser"; Value = $true } + ) + } + @{ + Id = "2.3" + Task = "Enable Information Bar for Outdated Plugins" + LockPrefs = @( + @{ Name = "plugins.hide_infobar_for_outdated_plugin"; Value = $false } + ) + } + @{ + Id = "2.4" + Task = "Set Update Interval Time Checks" + LockPrefs = @( + @{ Name = "app.update.interval"; Value = 43200 } + ) + } + @{ + Id = "2.5" + Task = "Set Update Wait Time Prompt" + LockPrefs = @( + @{ Name = "app.update.promptWaitTime"; Value = 172800 } + ) + } + @{ + Id = "2.6" + Task = "Ensure Update-related UI Components are Displayed" + LockPrefs = @( + @{ Name = "app.update.silent"; Value = $false } + ) + } + @{ + Id = "2.7" + Task = "Set Search Provider Update Behavior" + LockPrefs = @( + @{ Name = "app.update.auto"; Value = $true } + @{ Name = "app.update.enabled"; Value = $true } + ) + } + # @{ + # Id = "3.1" + # Task = "Validate Proxy Settings" + # } + @{ + Id = "3.2" + Task = "Do Not Send Cross SSLTLS Referrer Header" + LockPrefs = @( + @{ Name = "network.http.sendSecureXSiteReferrer"; Value = $false } + ) + } + @{ + Id = "3.3" + Task = "Disable NTLM v1" + LockPrefs = @( + @{ Name = "network.auth.force-generic-ntlm-v1"; Value = $false } + ) + } + @{ + Id = "3.4" + Task = "Enable Warning For Phishy URLs" + LockPrefs = @( + @{ Name = "network.http.phishy-userpass-length"; Value = 1 } + ) + } + @{ + Id = "3.5" + Task = "Enable IDN Show Punycode" + LockPrefs = @( + @{ Name = "network.IDN_show_punycode"; Value = $true } + ) + } + @{ + Id = "3.6" + Task = "Set File URI Origin Policy" + LockPrefs = @( + @{ Name = "security.fileuri.strict_origin_policy"; Value = $true } + ) + } + @{ + Id = "3.7" + Task = "Disable Cloud Sync" + LockPrefs = @( + @{ Name = "services.sync.enabled"; Value = $false } + ) + } + @{ + Id = "3.8" + Task = "Disable WebRTC" + LockPrefs = @( + @{ Name = "media.peerconnection.enabled"; Value = $false } + @{ Name = "media.peerconnection.use_document_iceservers"; Value = $false } + ) + } + @{ + Id = "4.1" + Task = "Set SSL Override Behavior" + LockPrefs = @( + @{ Name = "browser.ssl_override_behavior"; Value = 0 } + ) + } + @{ + Id = "4.2" + Task = "Set Security TLS Version Maximum" + LockPrefs = @( + @{ Name = "security.tls.version.max"; Value = 3 } + ) + } + @{ + Id = "4.3" + Task = "Set Security TLS Version Minimum " + LockPrefs = @( + @{ Name = "security.tls.version.min"; Value = 1 } + ) + } + @{ + Id = "4.4" + Task = "Set OCSP Use Policy" + LockPrefs = @( + @{ Name = "security.OCSP.enabled"; Value = 1 } + ) + } + @{ + Id = "4.5" + Task = "Block Mixed Active Content" + LockPrefs = @( + @{ Name = "security.mixed_content.block_active_content"; Value = $true } + ) + } + @{ + Id = "4.6" + Task = "Set OCSP Response Policy" + LockPrefs = @( + @{ Name = "security.OCSP.require"; Value = $true } + ) + } + @{ + Id = "5.1" + Task = "Disallow JavaScripts Ability to Change the Status Bar Text" + LockPrefs = @( + @{ Name = "dom.disable_window_status_change"; Value = $true } + ) + } + @{ + Id = "5.2" + Task = "Disable Scripting of Plugins by JavaScript" + LockPrefs = @( + @{ Name = "security.xpconnect.plugin.unrestricted"; Value = $false } + ) + } + @{ + Id = "5.3" + Task = "Disallow JavaScripts Ability to Hide the Address Bar" + LockPrefs = @( + @{ Name = "dom.disable_window_open_feature.location"; Value = $true } + ) + } + @{ + Id = "5.4" + Task = "Disallow JavaScripts Ability to Hide the Status Bar" + LockPrefs = @( + @{ Name = "dom.disable_window_open_feature.status"; Value = $true } + ) + } + @{ + Id = "5.5" + Task = "Disable Closing of Windows via Scripts" + LockPrefs = @( + @{ Name = "dom.allow_scripts_to_close_windows"; Value = $false } + ) + } + @{ + Id = "5.6" + Task = "Block Pop-up Windows" + LockPrefs = @( + @{ Name = "privacy.popups.policy"; Value = 1 } + ) + } + @{ + Id = "5.7" + Task = "Disable Displaying JavaScript in History URLs" + LockPrefs = @( + @{ Name = "browser.urlbar.filter.javascript"; Value = $true } + ) + } + @{ + Id = "6.1" + Task = "Disallow Credential Storage" + LockPrefs = @( + @{ Name = "signon.rememberSignons"; Value = $false } + ) + } + @{ + Id = "6.2" + Task = "Do Not Accept Third Party Cookies" + LockPrefs = @( + @{ Name = "network.cookie.cookieBehavior"; Value = 1 } + ) + } + @{ + Id = "6.3" + Task = "Tracking Protection" + LockPrefs = @( + @{ Name = "privacy.donottrackheader.enabled"; Value = $true } + @{ Name = "privacy.donottrackheader.value"; Value = 1 } + @{ Name = "privacy.trackingprotection.enabled"; Value = $true } + @{ Name = "privacy.trackingprotection.pbmode"; Value = $true } + ) + } + @{ + Id = "6.4" + Task = "Set Delay for Enabling Security Sensitive Dialog Boxes" + LockPrefs = @( + @{ Name = "security.dialog_enable_delay"; Value = 2000 } + ) + } + @{ + Id = "6.5" + Task = "Disable Geolocation Serivces" + LockPrefs = @( + @{ Name = "geo.enabled"; Value = $false } + ) + } + @{ + Id = "7.1" + Task = "Secure Application Plug-ins" + LockPrefs = @( + @{ Name = "browser.helperApps.alwaysAsk.force"; Value = $true } + ) + } + @{ + Id = "7.2" + Task = "Disabling Auto-Install of Add-ons" + LockPrefs = @( + @{ Name = "xpinstall.whitelist.required"; Value = $true } + ) + } + @{ + Id = "7.3" + Task = "Enable Extension Block List" + LockPrefs = @( + @{ Name = "extensions.blocklist.enabled"; Value = $true } + ) + } + @{ + Id = "7.4" + Task = "Set Extension Block List Interval" + LockPrefs = @( + @{ Name = "extensions.blocklist.interval"; Value = 86400 } + ) + } + @{ + Id = "7.5" + Task = "Enable Warning for External Protocol Handler" + LockPrefs = @( + @{ Name = "network.protocol-handler.warn-external-default"; Value = $true } + ) + } + @{ + Id = "7.6" + Task = "Disable Popups Initiated by Plugins" + LockPrefs = @( + @{ Name = "privacy.popups.disable_from_plugins"; Value = 2 } + ) + } + @{ + Id = "7.7" + Task = "Enable Extension Auto Update" + LockPrefs = @( + @{ Name = "extensions.update.autoUpdateDefault"; Value = $true } + ) + } + @{ + Id = "7.8" + Task = "Enable Extension Update" + LockPrefs = @( + @{ Name = "extensions.update.enabled"; Value = $true } + ) + } + @{ + Id = "7.9" + Task = "Set Extension Update Interval Time Checks" + LockPrefs = @( + @{ Name = "extensions.update.interval"; Value = 86400 } + ) + } + @{ + Id = "8.1" + Task = "Enable Virus Scanning for Downloads" + LockPrefs = @( + @{ Name = "browser.download.manager.scanWhenDone"; Value = $true } + ) + } + @{ + Id = "8.2" + Task = "Disable JAR from Opening Unsafe File Types" + LockPrefs = @( + @{ Name = "network.jar.open-unsafe-types"; Value = $false } + ) + } + @{ + Id = "8.3" + Task = "Block Reported Web Forgeries" + LockPrefs = @( + @{ Name = "browser.safebrowsing.enabled"; Value = $true } + ) + } + @{ + Id = "8.4" + Task = "Block Reported Attack Sites" + LockPrefs = @( + @{ Name = "browser.safebrowsing.malware.enabled"; Value = $true } + ) + } + ) +} + +$DisaRequirements = @{ + # RegistrySettings = @( + # @{ + # Id = "DTBF003" + # Task = "Installed version of Firefox unsupported." + # Path = "HKLM\Software\Mozilla\Mozilla Firefox\CurrentVersion" + # Name = "firefox.exe" + # Value = 0 # is equal to or greater than 50.1.x (or ESR 45.7.x) + # } + # ) + FirefoxLockPrefSettings = @( + @{ + Id = "DTBF030" + Task = "Firewall traversal from remote host must be disabled." + LockPrefs = @( + @{ Name = "security.enable_tls"; Value = $true } + @{ Name = "security.tls.version.min"; Value = 2 } + @{ Name = "security.tls.version.max"; Value = 3 } + ) + } + @{ + Id = "DTBF050" + Task = "FireFox is configured to ask which certificate to present to a web site when a certificate is required." + LockPrefs = @( + @{ Name = "security.default_personal_cert"; Value = "Ask Every Time" } + ) + } + # @{ # Not set - in CIS Benchmarks + # Id = "DTBF080" + # Task = "Firefox application is set to auto-update." + # } + @{ + Id = "DTBF085" + Task = "Firefox automatically checks for updated version of installed Search plugins." + LockPrefs = @( + @{ Name = "browser.search.update"; Value = $false } + ) + } + @{ + Id = "DTBF090" + Task = "Firefox automatically updates installed add-ons and plugins." + LockPrefs = @( + @{ Name = "extensions.update.enabled"; Value = $false } + ) + } + @{ + Id = "DTBF105" + Task = "Network shell protocol is enabled in FireFox." + LockPrefs = @( + @{ Name = "network.protocol-handler.external.shell"; Value = $false } + ) + } + # @{ # no longer available + # Id = "DTBF110" + # Task = "Firefox is not configured to prompt a user before downloading and opening required file types." + # } + # @{ # no longer available + # Id = "DTBF130" + # Task = "Firefox is not configured to provide warnings when a user switches from a secure (SSL-enabled) to a non-secure page." + # } + @{ + Id = "DTBF140" + Task = "Firefox formfill assistance option is disabled." + LockPrefs = @( + @{ Name = "browser.formfill.enable"; Value = $false } + ) + } + @{ + Id = "DTBF150" + Task = "Firefox is configured to autofill passwords." + LockPrefs = @( + @{ Name = "signon.autofillForms"; Value = $false } + ) + } + # @{ # Not set - in CIS Benchmarks + # Id = "DTBF160" + # Task = "FireFox is configured to use a password store with or without a master password." + # } + # @{ # Not set - see CIS benchmark 5.4_L1_Disallow_JavaScripts_Ability_to_Hide_the_Status_Bar + # Id = "DTBF180" + # Task = "FireFox is not configured to block pop-up windows. + # } + @{ + Id = "DTBF181" + Task = "FireFox is configured to allow JavaScript to move or resize windows." + LockPrefs = @( + @{ Name = "dom.disable_window_move_resize"; Value = $true } + ) + } + @{ + Id = "DTBF183" + Task = " Firefox is configured to allow JavaScript to disable or replace context menus." + LockPrefs = @( + @{ Name = "dom.event.contextmenu.enabled"; Value = $false } + ) + } + # @{ # Not set - in CIS Benchmarks + # Id = "DTBF184" + # Task = "Firefox is configured to allow JavaScript to hide or change the status bar." + # } + # @{ # no longer available + # Id = "DTBF186" + # Task = "Extensions install must be disabled." + # } + @{ + Id = "DTBF190" + Task = "Background submission of information to Mozilla must be disabled." + LockPrefs = @( + @{ Name = "datareporting.policy.dataSubmissionEnabled"; Value = $false } + @{ Name = "datareporting.healthreport.service.enabled"; Value = $false } + @{ Name = "datareporting.healthreport.uploadEnabled"; Value = $false } + ) + } + ) +} + +#endregion + +#region helper classes +class LockPrefSetting { + [string] $Name + $Value +} +#endregion + +#region Helper functions +function Get-FirefoxInstallDirectory { + if (Test-Path 'HKLM:\SOFTWARE\WOW6432Node\Mozilla\Mozilla Firefox\') { + $firefoxPath = 'HKLM:\SOFTWARE\WOW6432Node\Mozilla\Mozilla Firefox\' + }if (Test-Path 'HKLM:\SOFTWARE\Mozilla\Mozilla Firefox\') { + $firefoxPath = 'HKLM:\SOFTWARE\Mozilla\Mozilla Firefox\' + } + if(-not($null -eq $firefoxPath)){ + $currentFirefox = Get-ChildItem -Path $firefoxPath | Select-Object -Last 1 + $installDir = $currentFirefox | Get-ChildItem | Where-Object PSChildName -EQ "Main" + return $installDir | Get-ItemProperty | Select-Object -ExpandProperty "Install Directory" + } + else{ + Write-Output "Mozilla Firefox is not installed on OS" + } + # $firefoxPath = "HKLM:\SOFTWARE\WOW6432Node\Mozilla\Mozilla Firefox\" + # if (-not (Test-Path $firefoxPath)) { + # $firefoxPath = "HKLM:\SOFTWARE\Mozilla\Mozilla Firefox\" + # } +} + +function Get-FirefoxLocalSettingsFile { + return "{0}\defaults\pref\local-settings.js" -f (Get-FirefoxInstallDirectory) +} + +function Get-FirefoxMozillaCfgFileName { + $localSettingsFilePath = Get-FirefoxLocalSettingsFile + $content = if (Test-Path $localSettingsFilePath) { Get-Content $localSettingsFilePath } else { $null } + $filename = $content | ForEach-Object { + if ($_ -match "^pref\(`"general\.config\.filename`",\s?`"([\w\-. ]+\.cfg)`"\);") { + return $Matches[1] + } + return $null + } | Where-Object { $null -ne $_ } | Select-Object -Last 1 + + if ($null -eq $filename) { + return "mozilla.cfg" + } + + return $filename +} + +function Get-FirefoxMozillaCfgFile { + return "{0}\{1}" -f (Get-FirefoxInstallDirectory), (Get-FirefoxMozillaCfgFileName) +} + +function Get-FirefoxLockPrefs { + if (-not (Test-Path (Get-FirefoxMozillaCfgFile))) { + return $null + } + + $regex = "^lockPref\s*\(\s*`"([\w.-]+)`"\s*,\s*({0}|{1}|{2})\s*\);" -f @( + "(?true|false)" + "(?\d+)" + "`"(?(\\.|[^`"\\])*)`"" + ) + + $currentLockPrefs = Get-Content (Get-FirefoxMozillaCfgFile) | ForEach-Object { + if ($_ -match $regex) { + $value = $null + if ($Matches.Keys -contains "bool") { + $value = [bool]::Parse($Matches["bool"]) + } + elseif ($Matches.Keys -contains "number") { + $value = [int]::Parse($Matches["number"]) + } + elseif ($Matches.Keys -contains "string") { + $value = $Matches["string"] + } + + [LockPrefSetting]@{ Name = $Matches[1]; Value = $value } + } + } | Where-Object { $null -ne $_ } + + return $currentLockPrefs +} +#endregion + +#region Audit functions +function Get-RegistryAudit { + [CmdletBinding()] + Param( + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] $Id, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] $Task, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] $Path, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] $Name, + + [Parameter(ValueFromPipelineByPropertyName = $true)] + [AllowEmptyString()] + [object[]] $Value, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [ScriptBlock] $Predicate, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [String] $ExpectedValue, + + [Parameter(ValueFromPipelineByPropertyName = $true)] + [bool] $DoesNotExist = $false + ) + + process { + try { + $regValues = Get-ItemProperty -ErrorAction Stop -Path $Path -Name $Name ` + | Select-Object -ExpandProperty $Name + + if (-not (& $Predicate $regValues)) { + $regValue = $regValues -join ", " + + return @{ + Id = $Id + Task = $Task + Message = "Registry value: $regValue. Differs from allowed value: $ExpectedValue." + Status = "False" + } + } + } + catch [System.Management.Automation.PSArgumentException] { + if ($DoesNotExist) { + return @{ + Id = $Id + Task = $Task + Message = "Compliant. Registry value not set." + Status = "True" + } + } + + return @{ + Id = $Id + Task = $Task + Message = "Registry value not found." + Status = "False" + } + } + catch [System.Management.Automation.ItemNotFoundException] { + if ($DoesNotExist) { + return @{ + Id = $Id + Task = $Task + Message = "Compliant. Registry value not set." + Status = "True" + } + } + + return @{ + Id = $Id + Task = $Task + Message = "Registry key not found." + Status = "False" + } + } + + return @{ + Id = $Id + Task = $Task + Message = "Compliant" + Status = "True" + } + } +} + +function Get-FirefoxLocalSettingsFileAudit { + $Id = "1.1" + $Task = "Create local-settings.js file" + + if (-not (Test-Path (Get-FirefoxLocalSettingsFile))){ + return @{ + Id = $Id + Task = $Task + Message = "local-settings.js file does not exist." + Status = "False" + } + } + + $generalConfigFilename = Get-Content (Get-FirefoxLocalSettingsFile) | Where-Object { + $_ -match "^pref\s*\(\s*`"general\.config\.filename`"\s*,\s*`"([\w\-. ]+\.cfg)`"\s*\);" + } + + if ($generalConfigFilename.Count -eq 0) { + return @{ + Id = $Id + Task = $Task + Message = "File does not set 'general.config.filename'" + Status = "False" + } + } + + $generalConfigObscure = Get-Content (Get-FirefoxLocalSettingsFile) | Where-Object { + $_ -match "^pref\s*\(\s*`"general\.config\.obscure_value`"\s*,\s*0\s*\);" + } + + if ($generalConfigObscure.Count -eq 0) { + return @{ + Id = $Id + Task = $Task + Message = "File does not set 'general.config.obscure' = 0" + Status = "False" + } + } + + return @{ + Id = $Id + Task = $Task + Message = "Compliant" + Status = "True" + } +} + +function Get-FirefoxMozillaCfgFileAudit { + $name = Get-FirefoxMozillaCfgFileName + + $Id = "1.3" + $Task = "Create $name file" + + if (-not (Test-Path (Get-FirefoxMozillaCfgFile))){ + return @{ + Id = $Id + Task = $Task + Message = "$name file does not exist." + Status = "False" + } + } + + return @{ + Id = $Id + Task = $Task + Message = "Compliant" + Status = "True" + } +} + +function Get-FileAudit { + [CmdletBinding()] + Param( + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] $Id, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] $Task, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] $Path, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [scriptblock] $Predicate + ) + + process { + if (-not (Test-Path $Path)) { + return @{ + Id = $Id + Task = $Task + Message = "File does not exist." + Status = "False" + } + } + + if (-not (&$Predicate (Get-Content $Path))) { + return @{ + Id = $Id + Task = $Task + Message = "File does not match predicate." + Status = "False" + } + } + + return @{ + Id = $Id + Task = $Task + Message = "Compliant." + Status = "True" + } + } +} + +function Get-LockPrefSettingAudit { + [CmdletBinding()] + Param( + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] $Id, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] $Task, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [array] $LockPrefs, + + [LockPrefSetting[]] $CurrentLockPrefs = (Get-FirefoxLockPrefs) + ) + + process { + if ($null -eq $CurrentLockPrefs) { + return @{ + Id = $Id + Task = $Task + Message = "general config does not exist." + Status = "None" + } + } + + $missingLockPrefs = $LockPrefs | Where-Object { + $LockPref = $_ + # LockPref not in currentLockPrefs + ($currentLockPrefs | Where-Object { + ($_.Name -eq $LockPref.Name) -and ($_.Value -is $LockPref.Value.GetType()) -and ($_.Value -eq $LockPref.Value) + }).Count -eq 0 + } + + if ($missingLockPrefs.Count -gt 0) { + $msg = ($missingLockPrefs | ForEach-Object { "lockPref(`"{0}`", {1})" -f $_.Name, $_.Value }) -join "; " + + return @{ + Id = $Id + Task = $Task + Message = "Missing lockprefs: $msg." + Status = "False" + } + } + + return @{ + Id = $Id + Task = $Task + Message = "Compliant." + Status = "True" + } + } +} +#endregion + +$currentLockPrefs = Get-FirefoxLockPrefs + +[Report] @{ + Title = 'Mozilla Firefox Audit Report' + ModuleName = 'ATAPAuditor' + BasedOn = @( + 'CIS Mozilla Firefox 38 ESR Benchmark, Version: 1.0.0, Date: 2015-12-31' + 'DISA Mozilla FireFox Security Technical Implementation Guide, Version: V4R24, Date: 2019-01-25' + ) + Sections = @( + [ReportSection] @{ + Title = 'CIS Benchmarks' + Description = 'This section contains all CIS benchmarks' + Subsections = @( + [ReportSection] @{ + Title = "Configure Locked Preferences" + AuditInfos = @( + Get-FirefoxLocalSettingsFileAudit + # missing 1.2 + Get-FirefoxMozillaCfgFileAudit + # missing 1.4 + # missing 1.5 + ) + } + [ReportSection] @{ + Title = "Preference Settings" + AuditInfos = foreach ($setting in $CisBenchmarks.FirefoxLockPrefSettings) { + $obj = New-Object -TypeName psobject -Property $setting + Write-Output ($obj | Get-LockPrefSettingAudit -CurrentLockPrefs $currentLockPrefs) + } + } + ) + } + [ReportSection] @{ + Title = 'DISA Recommendations' + Description = 'This section contains all DISA recommendations' + Subsections = @( + [ReportSection] @{ + Title = "Preference Settings" + AuditInfos = foreach ($setting in $DisaRequirements.FirefoxLockPrefSettings) { + $obj = New-Object -TypeName psobject -Property $setting + Write-Output ($obj | Get-LockPrefSettingAudit -CurrentLockPrefs $currentLockPrefs) + } + } + ) + } + ) +} \ No newline at end of file diff --git a/ATAPAuditor/Reports/Red Hat Enterprise Linux 9.ps1 b/ATAPAuditor/Reports/Red Hat Enterprise Linux 9.ps1 new file mode 100644 index 0000000..d03730e --- /dev/null +++ b/ATAPAuditor/Reports/Red Hat Enterprise Linux 9.ps1 @@ -0,0 +1,19 @@ +[Report] @{ + Title = "Red Hat Enterprise Linux 9" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Red Hat Enterprise Linux 9 version 2.0.0" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains the general benchmark results" + SubSections = @( + [ReportSection] @{ + Title = 'CIS Red Hat Enterprise Linux 9' + AuditInfos = Test-AuditGroup "Red Hat Enterprise Linux 9-CIS-2.0.0" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/SUSE 15.ps1 b/ATAPAuditor/Reports/SUSE 15.ps1 new file mode 100644 index 0000000..f4ec3f1 --- /dev/null +++ b/ATAPAuditor/Reports/SUSE 15.ps1 @@ -0,0 +1,19 @@ +[Report] @{ + Title = "SUSE Enterprise 15" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS SUSE Linux 15 version 1.1.1" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains the general benchmark results" + SubSections = @( + [ReportSection] @{ + Title = 'CIS SUSE Linux 15' + AuditInfos = Test-AuditGroup "SUSE Linux Enterprise 15-CIS-1.1.1" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Ubuntu 20.04.ps1 b/ATAPAuditor/Reports/Ubuntu 20.04.ps1 new file mode 100644 index 0000000..c2cc9f1 --- /dev/null +++ b/ATAPAuditor/Reports/Ubuntu 20.04.ps1 @@ -0,0 +1,19 @@ +[Report] @{ + Title = "Ubuntu 20.04 Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Ubuntu Linux 20.04 version 1.1.0" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains the general benchmark results" + SubSections = @( + [ReportSection] @{ + Title = 'CIS Ubuntu Linux 20.04' + AuditInfos = Test-AuditGroup "Ubuntu Linux 20.04-CIS-1.1.0" + } + ) + } + ) +} diff --git a/ATAPAuditor/Reports/Ubuntu 22.04.ps1 b/ATAPAuditor/Reports/Ubuntu 22.04.ps1 new file mode 100644 index 0000000..c9ec961 --- /dev/null +++ b/ATAPAuditor/Reports/Ubuntu 22.04.ps1 @@ -0,0 +1,19 @@ +[Report] @{ + Title = "Ubuntu 22.04 Report" + ModuleName = "ATAPAuditor" + BasedOn = @( + "CIS Ubuntu Linux 22.04 version 2.0.0" + ) + Sections = @( + [ReportSection] @{ + Title = "CIS Benchmarks" + Description = "This section contains the general benchmark results" + SubSections = @( + [ReportSection] @{ + Title = 'CIS Ubuntu Linux 22.04' + AuditInfos = Test-AuditGroup "Ubuntu Linux 22.04-CIS-2.0.0" + } + ) + } + ) +} diff --git a/ATAPAuditor/Resources/FirefoxPreferences.ps1 b/ATAPAuditor/Resources/FirefoxPreferences.ps1 new file mode 100644 index 0000000..f6e1474 --- /dev/null +++ b/ATAPAuditor/Resources/FirefoxPreferences.ps1 @@ -0,0 +1,134 @@ +function doFirefox { + param ( + [Parameter(Mandatory = $true)] + [string]$path + ) + $currentFirefoxRegKey = Get-ChildItem -Path $path | Select-Object -Last 1 + $installDirRegKey = $currentFirefoxRegKey | Get-ChildItem | Where-Object PSChildName -EQ 'Main' + $InstallationPath = $installDirRegKey | Get-ItemProperty | Select-Object -ExpandProperty 'Install Directory' + + # Calculate Firefox local-settings path + $LocalSettingsPath = "$InstallationPath\defaults\pref\local-settings.js" + + # Calculate Firefox config path + $preferenceConfigFilename = 'mozilla.cfg' + if (Test-Path $LocalSettingsPath) { + foreach ($line in (Get-Content $LocalSettingsPath)) { + if ($_ -match "^pref\(`"general\.config\.filename`",\s?`"([\w\-. ]+\.cfg)`"\);") { + $preferenceConfigFilename = $Matches[1] + } + } + } + $PreferenceConfigPath = "$InstallationPath\$preferenceConfigFilename" + + # Gather lines into lockPref list + # if (-not (Test-Path $LocalSettingsPath) -or + # -not (Test-Path $PreferenceConfigPath)) { + # return $null + # } + + $boolRegex = '(?true|false)' + $numberRegex = '(?\d+)' + $stringRegex = '"(?(\\.|[^`"\\])*)"' + $lineRegex = "^lockPref\s*\(\s*`"([\w.-]+)`"\s*,\s*({0}|{1}|{2})\s*\);" -f $boolRegex, $numberRegex, $stringRegex + + $LockedPreferences = @() + if (Test-Path $PreferenceConfigPath) { + foreach ($line in (Get-Content $PreferenceConfigPath)) { + if ($line -match $lineRegex) { + $value = $null + if ($Matches.Keys -contains "bool") { + $value = [bool]::Parse($Matches["bool"]) + } + elseif ($Matches.Keys -contains "number") { + $value = [int]::Parse($Matches["number"]) + } + elseif ($Matches.Keys -contains "string") { + $value = $Matches["string"] + } + + $LockedPreferences += @{ Name = $Matches[1]; Value = $value } + } + } + } + + return [PSCustomObject] @{ + InstallationPath = $InstallationPath + LocalSettingsPath = $LocalSettingsPath + PreferenceConfigPath = $PreferenceConfigPath + LockedPreferences = $LockedPreferences + } + + + $currentFirefoxRegKey = Get-ChildItem -Path $path | Select-Object -Last 1 + $installDirRegKey = $currentFirefoxRegKey | Get-ChildItem | Where-Object PSChildName -EQ 'Main' + $InstallationPath = $installDirRegKey | Get-ItemProperty | Select-Object -ExpandProperty 'Install Directory' + + # Calculate Firefox local-settings path + $LocalSettingsPath = "$InstallationPath\defaults\pref\local-settings.js" + + # Calculate Firefox config path + $preferenceConfigFilename = 'mozilla.cfg' + if (Test-Path $LocalSettingsPath) { + foreach ($line in (Get-Content $LocalSettingsPath)) { + if ($_ -match "^pref\(`"general\.config\.filename`",\s?`"([\w\-. ]+\.cfg)`"\);") { + $preferenceConfigFilename = $Matches[1] + } + } + } + $PreferenceConfigPath = "$InstallationPath\$preferenceConfigFilename" + + # Gather lines into lockPref list + # if (-not (Test-Path $LocalSettingsPath) -or + # -not (Test-Path $PreferenceConfigPath)) { + # return $null + # } + + $boolRegex = '(?true|false)' + $numberRegex = '(?\d+)' + $stringRegex = '"(?(\\.|[^`"\\])*)"' + $lineRegex = "^lockPref\s*\(\s*`"([\w.-]+)`"\s*,\s*({0}|{1}|{2})\s*\);" -f $boolRegex, $numberRegex, $stringRegex + + $LockedPreferences = @() + if (Test-Path $PreferenceConfigPath) { + foreach ($line in (Get-Content $PreferenceConfigPath)) { + if ($line -match $lineRegex) { + $value = $null + if ($Matches.Keys -contains "bool") { + $value = [bool]::Parse($Matches["bool"]) + } + elseif ($Matches.Keys -contains "number") { + $value = [int]::Parse($Matches["number"]) + } + elseif ($Matches.Keys -contains "string") { + $value = $Matches["string"] + } + + $LockedPreferences += @{ Name = $Matches[1]; Value = $value } + } + } + } + + return [PSCustomObject] @{ + InstallationPath = $InstallationPath + LocalSettingsPath = $LocalSettingsPath + PreferenceConfigPath = $PreferenceConfigPath + LockedPreferences = $LockedPreferences + } +} + +# Calculate Firefox installation path +if (Test-Path 'HKLM:\SOFTWARE\WOW6432Node\Mozilla\Mozilla Firefox\') { + $firefoxRegKeyPath = 'HKLM:\SOFTWARE\WOW6432Node\Mozilla\Mozilla Firefox\' + doFirefox -path $firefoxRegKeyPath +}if (Test-Path 'HKLM:\SOFTWARE\Mozilla\Mozilla Firefox\') { + $firefoxRegKeyPath = 'HKLM:\SOFTWARE\Mozilla\Mozilla Firefox\' + doFirefox -path $firefoxRegKeyPath +}else { + return [PSCustomObject] @{ + InstallationPath = "Seems like Firefox is not installed on this system." + LocalSettingsPath = "Seems like Firefox is not installed on this system." + PreferenceConfigPath = "Seems like Firefox is not installed on this system." + LockedPreferences = "Seems like Firefox is not installed on this system." + } +} \ No newline at end of file diff --git a/ATAPAuditor/Resources/WindowsSecurityPolicy.ps1 b/ATAPAuditor/Resources/WindowsSecurityPolicy.ps1 new file mode 100644 index 0000000..e33d565 --- /dev/null +++ b/ATAPAuditor/Resources/WindowsSecurityPolicy.ps1 @@ -0,0 +1,48 @@ +using module .\..\Helpers\SecurityPolicy.psm1 + +$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) +$isAdministrator = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) + +if(-not $isAdministrator){ + throw "Administrator privileges are required!" +} + +# get a temporary file to save and process the secedit settings +$securityPolicyPath = Join-Path -Path $env:TEMP -ChildPath 'SecurityPolicy.inf' + +# export the secedit settings to this temporary file +Write-Verbose "[WindowsSecurityPolicy] Exporting local security policies from secedit into tempory file: $securityPolicyPath" +secedit.exe /export /cfg $securityPolicyPath | Out-Null + +$config = @{} +switch -regex -file $securityPolicyPath { + "^\[(.+)\]" { # Section + $section = $matches[1] + $config[$section] = @{} + } + "(.+?)\s*=(.*)" { # Key + $name = $matches[1] + $value = $matches[2] -replace "\*" + $config[$section][$name] = $value + } +} + +Write-Verbose "[WindowsSecurityPolicy] Converting identities in 'Privilege Rights' section" +$privilegeRights = @{} +foreach ($key in $config["Privilege Rights"].Keys) { + # Make all accounts SIDs + $accounts = $($config["Privilege Rights"][$key] -split ",").Trim() ` + | ConvertTo-NTAccountUser -Verbose:$VerbosePreference ` + | Where-Object { $null -ne $_ } + $privilegeRights[$key] = $accounts +} +$config["Privilege Rights"] = $privilegeRights + +# sanitize input +$systemAccess = @{} +foreach ($key in $config["System Access"].Keys) { + $systemAccess[$key] = $config["System Access"][$key].Trim() +} +$config["System Access"] = $systemAccess + +return $config \ No newline at end of file diff --git a/ATAPHtmlReport/ATAPHtmlReport.Tests.ps1 b/ATAPHtmlReport/ATAPHtmlReport.Tests.ps1 new file mode 100644 index 0000000..10c8841 --- /dev/null +++ b/ATAPHtmlReport/ATAPHtmlReport.Tests.ps1 @@ -0,0 +1,91 @@ +<# +BSD 3-Clause License + +Copyright (c) 2023, FB Pro GmbH +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#> + +Import-Module "./ATAPHtmlReport" -Force + +class MyAudit { + [string] $Id + [string] $Task + [string] $Status + [string] $Message +} + +Describe "ATAPHtmlReport" { + InModuleScope ATAPHtmlReport { + $testPath = "$PSScriptRoot\testreport.html" + $args = @{ + Path = $testPath + Title = "My Benchmark Report" + ModuleName = "MyAudit" + BasedOn = @( + "My Benchmark v1.0.0 - 10-05-2017" + "My Benchmark 2 v1.0.0 - 10-05-2017" + "My Benchmark 3 v1.0.0 - 10-05-2017" + ) + } + Get-ATAPHtmlReport @args -Sections @( + [PSCustomObject]@{ + Title = "Section 1" + AuditInfos = @( + [MyAudit]@{ Id = "1.1"; Task = "Ensure something"; Message = "All Good"; Status = 'True' } + [MyAudit]@{ Id = "1.2"; Task = "Ensure something"; Message = "All Good"; Status = 'True' } + [MyAudit]@{ Id = "1.3"; Task = "Ensure something"; Message = "All Good"; Status = 'True' } + [MyAudit]@{ Id = "1.4"; Task = "Ensure something"; Message = "Not run"; Status = 'None' } + ) + }, + [PSCustomObject]@{ + Title = "Section 2" + SubSections = @( + [PSCustomObject]@{ + Title = " Section 2.1" + AuditInfos = @( + [MyAudit]@{ Id = "2.1.1"; Task = "Ensure something else"; Message = "All Good"; Status = 'Warning' } + [MyAudit]@{ Id = "2.1.2"; Task = "Ensure something entirely different"; Message = "All good"; Status = 'True' } + ) + }, + [PSCustomObject]@{ + Title = "Section 2.2" + AuditInfos = @( + [MyAudit]@{ Id = "2.2.1"; Task = "Ensure something entirely different"; Message = "Something went wrong"; Status = 'False' } + [MyAudit]@{ Id = "2.2.2"; Task = "Text overflow can only happen on block or inline-block level elements, because the element needs to have a width in order to be overflow-ed. The overflow happens in the direction as determined by the direction property or related attributes."; Message = "All Good"; Status = 'True' } + [MyAudit]@{ Id = "2.1.2"; Task = "Ensure something entirely different"; Message = "Not quite good"; Status = 'Warning' } + ) + } + ) + } + ) + + It "Get-ATAPHtmlReport" { + Test-Path $testPath | Should Be $true + } + } +} diff --git a/ATAPHtmlReport/ATAPHtmlReport.psd1 b/ATAPHtmlReport/ATAPHtmlReport.psd1 new file mode 100644 index 0000000..d7e4272 --- /dev/null +++ b/ATAPHtmlReport/ATAPHtmlReport.psd1 @@ -0,0 +1,146 @@ +<# +BSD 3-Clause License + +Copyright (c) 2023, FB Pro GmbH +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#> + +@{ + +# Script module or binary module file associated with this manifest. +RootModule = 'ATAPHtmlReport.psm1' + +# Version number of this module. +ModuleVersion = '1.13.5' + +# Supported PSEditions +# CompatiblePSEditions = @() + +# ID used to uniquely identify this module +GUID = 'b732e8cd-6500-4da8-ac96-ab60087c739b' + +# Author of this module +Author = 'Benedikt Böhme, Patrick Helbach, Steffen Winternheimer, Robin Wernz' + +# Company or vendor of this module +CompanyName = 'FB Pro GmbH' + +# Copyright statement for this module +Copyright = '(c) 2023 FB Pro GmbH. All rights reserved.' + +# Description of the functionality provided by this module +Description = 'ATAPHtmlReport serves as the basis for HTML reports generated via ATAPAuditor.' + +# Minimum version of the Windows PowerShell engine required by this module +PowerShellVersion = '5.0' + +# Name of the Windows PowerShell host required by this module +# PowerShellHostName = '' + +# Minimum version of the Windows PowerShell host required by this module +# PowerShellHostVersion = '' + +# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. +# DotNetFrameworkVersion = '' + +# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. +# CLRVersion = '' + +# Processor architecture (None, X86, Amd64) required by this module +# ProcessorArchitecture = '' + +# Modules that must be imported into the global environment prior to importing this module +# RequiredModules = @() + +# Assemblies that must be loaded prior to importing this module +# RequiredAssemblies = @() + +# Script files (.ps1) that are run in the caller's environment prior to importing this module. +# ScriptsToProcess = @() + +# Type files (.ps1xml) to be loaded when importing this module +# TypesToProcess = @() + +# Format files (.ps1xml) to be loaded when importing this module +# FormatsToProcess = @() + +# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess +# NestedModules = @() + +# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. +FunctionsToExport = @('Get-ATAPHtmlReport', 'Get-ATAPHostInformation') + +# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. +CmdletsToExport = @() + +# Variables to export from this module +VariablesToExport = '' + +# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. +AliasesToExport = @() + +# DSC resources to export from this module +# DscResourcesToExport = @() + +# List of all modules packaged with this module +# ModuleList = @() + +# List of all files packaged with this module +# FileList = @() + +# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. +PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + Tags = @('reporting', 'auditing', 'benchmarks', 'fb-pro', 'html') + + # A URL to the license for this module. + LicenseUri = 'https://github.com/fbprogmbh/Audit-Test-Automation/blob/master/LICENSE' + + # A URL to the main website for this project. + ProjectUri = 'https://github.com/fbprogmbh/Audit-Test-Automation' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + } # End of PSData hashtable + +} # End of PrivateData hashtable + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} diff --git a/ATAPHtmlReport/ATAPHtmlReport.psm1 b/ATAPHtmlReport/ATAPHtmlReport.psm1 new file mode 100644 index 0000000..b69f49d --- /dev/null +++ b/ATAPHtmlReport/ATAPHtmlReport.psm1 @@ -0,0 +1,2125 @@ +<# +BSD 3-Clause License +Copyright (c) 2023, FB Pro GmbH +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#> + +$webIcon = @" + +"@ + +$mailIcon = @" + +"@ + +$phoneIcon = @" + +"@ +<# +icons from https://www.svgrepo.com/ + +#> +enum AuditInfoStatus { + True + False + Warning + None + Error +} + +$ScriptRoot = Split-Path -Parent $PSCommandPath + +$Settings = Import-PowerShellDataFile -Path "$ScriptRoot\Settings.psd1" +$ModuleVersion = (Import-PowerShellDataFile -Path "$ScriptRoot\ATAPHtmlReport.psd1").ModuleVersion + +$StatusValues = 'True', 'False', 'Warning', 'None', 'Error' +$AuditProperties = @{ Name = 'Id' }, @{ Name = 'Task' }, @{ Name = 'Message' }, @{ Name = 'Status' } + +#read in all information needed for Mitre Attack Mapping from json file +$global:CISToAttackMappingData = Get-Content -Raw "$PSScriptRoot\resources\CISToAttackMappingData.json" | ConvertFrom-Json + +function Get-MitreMappingMetaData { + <# + .SYNOPSIS + Returns the specified metadata to the mapping data + .EXAMPLE + Get-MitreMappingMetaData -Get BasedOn + Get-MitreMappingMetaData BasedOn + #> + param( + [Parameter(Mandatory)][ValidateSet('Version', 'BasedOn', 'Compatible')] + [string]$Get + ) + return $CISToAttackMappingData.'MappingMetaData'.$Get +} + +function Get-MitreTacticName { + <# + .SYNOPSIS + Returns the corresponding name for a given Mitre Tactic Id + + .EXAMPLE + Get-MitreTacticName TacticId 'TA0043' + #> + param( + [Parameter(Mandatory = $true)] + [string] + $TacticId + ) + + # $CISToAttackMappingData[AttackTactics][$tacticId] cannot be used because CISToAttackMappingData is a customObject and not a map + return $CISToAttackMappingData.'AttackTactics'.$tacticId +} + +function Get-MitreTactics { + <# + .SYNOPSIS + Returns a List of Mitre Tactic IDs for a given Mitre Technique Id + + .EXAMPLE + Get-MitreTactics -TechniqueID 'T1133' + #> + param( + [Parameter(Mandatory = $true)] + $TechniqueID + ) + return $CISToAttackMappingData.'TechniquesToTactis'.$TechniqueID +} + +function Get-MitreTechniqueName { + <# + .SYNOPSIS + Returns the name of a Mitre technique for a given Mitre Technique Id + + .EXAMPLE + Get-MitreTechniqueName -TechniqueID 'T1133' + #> + param( + [Parameter(Mandatory = $true)] + $TechniqueID + ) + return $CISToAttackMappingData.'AttackTechniques'.$TechniqueID.'name' +} + +function Test-CompatibleMitreReport { + <# + .SYNOPSIS + Returns if the report is compatible with the current mitre heatmap + + .EXAMPLE + Test-CompatibleMitreReport -Title "Windows 10 Report" -os "Win32NT" + #> + param( + [Parameter(Mandatory = $true)] + $Title, + [Parameter(Mandatory = $true)] + $os + ) + if (($Title -eq "Windows 10 Report" -or $Title -eq "Windows 11 Report" -or $Title -eq "Windows Server 2019 Audit Report" -or $Title -eq "Windows Server 2022 Audit Report") -and $os -match "Win32NT") { + return $true + } + else { + return $false + } +} + +function Get-MitreTechniqueCategories { + <# + .SYNOPSIS + Returns the categories of a Mitre technique in order to apply filters to the report. + Will return a string that provides all categories stored in the JSON file. + + .EXAMPLE + Get-MitreTechniqueCategories -TechniqueID 'T1133' + #> + param( + [Parameter(Mandatory = $true)] + $TechniqueID + ) + return $CISToAttackMappingData.'AttackTechniques'.$TechniqueID.'categories' +} + + +class MitreMap { + [System.Collections.Generic.Dictionary[string, [System.Collections.Generic.Dictionary[string, [System.Collections.Generic.Dictionary[string, AuditInfoStatus]]]]]] $Map + + MitreMap() { + $this.Map = @{} + + #read in techniques from json-file + $techniques = $global:CISToAttackMappingData.'AttackTechniques' + $tactics = $global:CISToAttackMappingData.'AttackTactics' + + foreach ($tacitc in $tactics.psobject.properties.name) { + $this.Map[$tacitc] = @{} + } + + #add all techniques and tactics to map + foreach ($technique in $techniques.psobject.properties.name) { + $tactics = Get-MitreTactics -TechniqueID $techniques.$technique.'ID' + foreach ($tactic in $tactics) { + if ($null -eq $this.Map[$tactic][$techniques.$technique.'ID']) { + $this.Map[$tactic][$techniques.$technique.'ID'] = @{} + } + } + } + } + + [void] Add($tactic, $technique, $id, $value) { + if ($tactic -and $technique -and $id -and $null -ne $value -and $tactic.GetType().Name -eq 'String' -and $technique.GetType().Name -eq 'String' -and $id.GetType().Name -eq 'String' -and $value.GetType().Name -eq 'AuditInfoStatus') { + if ($null -eq $this.Map[$tactic]) { + $this.Map[$tactic] = @{} + } + if ($null -eq $this.Map[$tactic][$technique]) { + $this.Map[$tactic][$technique] = @{} + } + $this.Map[$tactic][$technique][$id] = $value + } + else { + if (!$tactic) { + Write-Error -Message 'Could not add value to Map. $tactic is $null or empty' -Category InvalidType + } + elseif (!$technique) { + Write-Error -Message 'Could not add value to Map. $technique is $null or empty' -Category InvalidType + } + elseif (!$id) { + Write-Error -Message 'Could not add value to Map. $id is $null or empty' -Category InvalidType + } + elseif ($null -eq $value) { + Write-Error -Message 'Could not add value to Map. $value is $null' -Category InvalidType + } + else { + Write-Error -Message 'Could not add value to Map' -Category InvalidType + } + } + } + + [void] Print() { + foreach ($tactic in $this.Map.Keys) { + Write-Host "$tactic = " + foreach ($technique in $this.Map[$tactic].Keys) { + Write-Host " $technique = " + foreach ($id in $this.Map[$tactic][$technique].Keys) { + Write-Host " $id = $($this.Map[$tactic][$technique][$id])" + } + } + } + } +} + +function get-MitreLink { + <# + .SYNOPSIS + Creates a url which points to the documentation of mitre for a given tactic or technique + + .PARAMETER id + id of the tactic or technique + + .PARAMETER type + one of 'tactic', 'technique' or 'mitigations' + + .EXAMPLE + get-MitreLink -type technique -id 'T1548' | Should -Be 'https://attack.mitre.org/techniques/T1548/' + #> + + param( + [string] $id, + [Parameter(Mandatory)][ValidateSet('tactics', 'techniques', 'mitigations')] + [string]$type + ) + + $url = 'https://attack.mitre.org/' + $url += "$type/$id/" + return $url +} + +function Join-ATAPReportStatus { + [CmdletBinding()] + [OutputType([string])] + param( + [Parameter(Mandatory = $true)] + [string[]] + $Statuses + ) + + if ($Statuses -contains 'False') { + return 'False' + } + elseif ($Statuses -contains 'Error') { + return 'Warning' + } + elseif ($Statuses -contains 'Warning') { + return 'Warning' + } + elseif ($Statuses -contains 'True') { + return 'True' + } + else { + return 'None' + } +} + +function htmlElement { + param( + [Parameter(Mandatory = $true, Position = 0)] + [string] + $ElementName, + + [Parameter(Mandatory = $true, Position = 1)] + [hashtable] + $Attributes, + + [Parameter(Mandatory = $true, Position = 2)] + [scriptblock] + $Children + ) + + $htmlAttributes = @() + foreach ($attribute in $Attributes.GetEnumerator()) { + $htmlAttributes += '{0}="{1}"' -f $attribute.Name, $attribute.Value + } + + [string[]]$htmlChildren = & $Children + + return '<{0} {1}>{2}' -f $ElementName, ($htmlAttributes -join ' '), ($htmlChildren -join '') +} + +function Get-SectionStatus { + param( + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [Alias('AuditInfos')] + [array] + $ConfigAudits, + + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [array] + $Subsections + ) + + process { + $allStatuses = @() + if ($null -ne $ConfigAudits) { + $allStatuses += $ConfigAudits.Status + } + if ($null -ne $Subsections) { + foreach ($subsection in $Subsections) { + $allStatuses += $subsection | Get-SectionStatus + } + } + return Join-ATAPReportStatus $allStatuses + } +} + +function Get-HtmlClassFromStatus { + param( + [Parameter(Mandatory = $true)] + [string] + $Status + ) + + process { + switch ($Status) { + 'True' { 'passed' } + 'False' { 'failed' } + 'Warning' { 'warning' } + 'None' { 'none' } + 'Error' { 'error' } + Default { "" } + } + } +} + +function Convert-SectionTitleToHtmlId { + param( + [Parameter(Mandatory = $true)] + [string] $Title + ) + + $charMap = { + switch ($_) { + ' ' { "-" } + '-' { "--" } + Default { $_ } + } + } + + return ([char[]]$Title | ForEach-Object $charMap) -join '' +} + +function CreateToc { + param( + [Parameter(Mandatory = $true)] + $title + ) + htmlElement 'li' @{} { + htmlElement 'a' @{ href = "#$($title)" } { "$($title)" } + } +} + + + +function CreateHashTable { + htmlElement 'div'@{id = "hashTableDiv" } { + htmlElement 'h2' @{style = "margin-top: 0;" } { "Overall integrity" } + htmlElement 'p' @{} { "This table outlines integrity checksums for each hardening recommendation. This allows for a quick comparison between reports by simply comparing provided hash values." } + htmlElement 'table'@{ id = "hashTable" } { + htmlElement 'thead' @{} { + htmlElement 'tr' @{} { + htmlElement 'th' @{style = "border: 1px solid var(--color-dark-gray); border-collapse: collapse; background-color: var(--color-dark-gray);" } { "Integrity Check for following scopes" } + htmlElement 'th' @{style = "border: 1px solid var(--color-dark-gray); border-collapse: collapse; background-color: var(--color-dark-gray);" } { "Checksum (SHA-256)" } + } + } + htmlElement 'tbody' @{id = "hashTableBody" } { + htmlElement 'tr' @{} { + #Scope + htmlElement 'td' @{style = "border: 1px solid var(--color-dark-gray); border-collapse: collapse;vertical-align: middle; " } { "Overall integrity check" } + #Checksum + htmlElement 'td' @{style = "border: 1px solid var(--color-dark-gray); border-collapse: collapse; " } { + htmlElement 'p' @{style = "padding-right: 20px;" } { "$($hashtable_sha256.Get_Item($Title))" } + } + } + + # $index = 0 + # $trColorSwitch = 0 + # foreach ($section in $Sections) { + # if ($trColorSwitch -eq 0) { + # htmlElement 'tr' @{style = "border: 1px solid #d2d2d2; border-collapse: collapse; background-color: #efefef;" } { + # #Scope + # htmlElement 'td' @{style = "border: 1px solid #d2d2d2; border-collapse:; vertical-align: middle; " } { "$($section.Title)" } + # #Checksum + # htmlElement 'td' @{style = "border: 1px solid #d2d2d2; border-collapse: collapse; " } { + # htmlElement 'p' @{style = "padding-right: 20px;" } { "$($hashtable_sha256.Get_Item($section.Title))" } + # } + # } + # $trColorSwitch = 1 + # } + # else { + # htmlElement 'tr' @{style = "border: 1px solid #d2d2d2; border-collapse: collapse;" } { + # #Scope + # htmlElement 'td' @{style = "border: 1px solid #d2d2d2; border-collapse:; vertical-align: middle; " } { "$($section.Title)" } + # #Checksum + # htmlElement 'td' @{style = "border: 1px solid #d2d2d2; border-collapse: collapse; " } { + # htmlElement 'p' @{style = "padding-right: 20px;" } { "$($hashtable_sha256.Get_Item($section.Title))" } + # } + # } + # $trColorSwitch = 0 + # } + # $index += 1 + # } + + $index = 0 + foreach ($section in $Sections) { + $trColorSwitch += 1 + $background = "" + if ($index%2 -eq 0) { + $background = "background-color: var(--color-light-gray);" + }else{ + $background = "" + } + htmlElement 'tr' @{style = "border: 1px solid var(--color-dark-gray); border-collapse: collapse;$($background)" } { + #Scope + htmlElement 'td' @{style = "border: 1px solid var(--color-dark-gray); border-collapse:; vertical-align: middle; " } { "$($section.Title)" } + #Checksum + htmlElement 'td' @{style = "border: 1px solid var(--color-dark-gray); border-collapse: collapse; " } { + htmlElement 'p' @{style = "padding-right: 20px;" } { "$($hashtable_sha256.Get_Item($section.Title))" } + } + } + $index += 1 + } + } + } + } +} + +function CreateReportContent { + param( + [Parameter(Mandatory = $true)] + $tests, + [Parameter(Mandatory = $true)] + $title + ) + $amountOfFailedTests = 0 + foreach ($test in $tests) { + if ($test.Status -eq 'False') { + $amountOfFailedTests ++ + } + } + #if at least one test is failed + if ($amountOfFailedTests -gt 0) { + htmlElement 'h2' @{ id = "$($title)"; class = "severityResultFalse" } { "$($title)" } + } + else { + htmlElement 'h2' @{ id = "$($title)"; class = "severityResultTrue" } { "$($title)" } + } + htmlElement 'table' @{class = 'audit-info'; style = 'margin-bottom: 50px; margin-top: 20px;' } { + htmlElement 'tbody' @{} { + htmlElement 'tr' @{} { + htmlElement 'th' @{} { "Id" } + htmlElement 'th' @{} { "Task" } + htmlElement 'th' @{} { "Message" } + htmlElement 'th' @{} { "Status" } + } + foreach ($test in $tests) { + htmlElement 'tr' @{} { + htmlElement 'td' @{} { "$($test.Id)" } + htmlElement 'td' @{} { "$($test.Task)" } + htmlElement 'td' @{} { "$($test.Message)" } + htmlElement 'td' @{} { + if ($test.Status -eq 'False') { + htmlElement 'span' @{class = "severityResultFalse" } { + "$($test.Status)" + } + } + elseif ($test.Status -eq 'True') { + htmlElement 'span' @{class = "severityResultTrue" } { + "$($test.Status)" + } + } + elseif ($test.Status -eq 'None') { + htmlElement 'span' @{class = "severityResultNone" } { + "$($test.Status)" + } + } + elseif ($test.Status -eq 'Warning') { + htmlElement 'span' @{class = "severityResultWarning" } { + "$($test.Status)" + } + } + elseif ($test.Status -eq 'Error') { + htmlElement 'span' @{class = "severityResultError" } { + "$($test.Status)" + } + } + } + } + } + } + } +} + + +function Get-HtmlTableRow { + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + $Audit + ) + + process { + # $properties = $Audit | Get-Member -MemberType Property + + htmlElement 'tr' @{} { + foreach ($property in $AuditProperties) { + $value = $Audit | Select-Object -ExpandProperty $property.Name + if ($Property.Name -eq 'Status') { + $class = Get-HtmlClassFromStatus $Audit.Status + $value = htmlElement 'span' @{ class = "auditstatus $class" } { $value } + } + htmlElement 'td' @{} { $value } + } + } + } +} + +function Get-HtmlToc { + param( + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] + $Title, + + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [array] + $Subsections, + + [string] + $Prefix = '' + ) + + process { + $id = Convert-SectionTitleToHtmlId -Title ($Prefix + $Title) + htmlElement 'li' @{} { + htmlElement 'a' @{ href = "#$id" } { $Title } + if ($null -ne $Subsections) { + htmlElement 'ul' @{} { + foreach ($subsection in $Subsections) { + $subsection | Get-HtmlToc -Prefix ($Prefix + $Title) + } + } + } + } + } +} + +function Merge-CisAuditsToMitreMap { + <# + .Synopsis + Merges the stati of multiple AuditInfos into a 2 dimensional map which can be indexd by the corresponding Mitre tactics an techniques. + This allows to simply find out how many Audits where succesfull for a given Mitre technique. + The result is a MitreMap Object. + + .PARAMETER Audit + An AuditTest Object containing the Audit results. Multiple can be passed from a pipeline + + .EXAMPLE + $mitreMap = $Sections | + Where-Object { $_.Title -eq "CIS Benchmarks" } | + ForEach-Object { return $_.SubSections } | + ForEach-Object { return $_.AuditInfos } | + Merge-CisAuditsToMitreMap + $mitreMap.Print() + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + $Audit + ) + Begin { + $json = $global:CISToAttackMappingData.'CISAttackMapping' + $mitreMap = [MitreMap]::new() + } + + Process { + $id = $Audit.Id + $technique1 = $json.$id.'Technique1' + $technique2 = $json.$id.'Technique2' + + if ($technique1) { + foreach ($tactic in Get-MitreTactics -TechniqueID $technique1) { + if ($tactic) { + $mitreMap.Add($tactic, $technique1, $id, $Audit.Status) + } + } + } + + if ($technique2) { + foreach ($tactic in Get-MitreTactics -TechniqueID $technique2) { + if ($tactic) { + $mitreMap.Add($tactic, $technique2, $id, $Audit.Status) + } + } + } + } + + End { + return [MitreMap] $mitreMap + } +} + +function Get-MitigationsFromFailedTests { + <# + .Synopsis + Returns a map with a array with all Techniques which had a failed test and the Mitigation. + + .PARAMETER Mappings + Is a mitre Mapping from Get-MitigationsFromFailedTests + + .EXAMPLE + $CISAMitigations = $Mappings.Map | Get-MitigationsFromFailedTests + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + $Mappings + ) + Begin { + $json = $global:CISToAttackMappingData.'CISAttackMapping' + #mapping with Mitigation IDs as keys + #array with all techniques where the mititgation is in the cisa paper and a tests failed + #mitigation from the cisa paper + $CISAMitigationsFromPaper = [ordered]@{ + 'M1017' = @{ + 'MitreTechniqueIDs' = @() + 'Mitigation' = 'Train users to be aware of access or manipulation attempts by an adversary to reduce the risk of successful spear-phishing and social engineering.' + } + 'M1018' = @{ + 'MitreTechniqueIDs' = @() + 'Mitigation' = 'Manage the creation, modification, use, and permissions associated to user accounts.' + } + 'M1021' = @{ + 'MitreTechniqueIDs' = @() + 'Mitigation' = 'Restrict or block certain websites.' + } + 'M1027' = @{ + 'MitreTechniqueIDs' = @() + 'Mitigation' = 'Set and enforce secure password policies for accounts.' + } + 'M1028' = @{ + 'MitreTechniqueIDs' = @() + 'Mitigation' = 'Make configuration changes related to the operating system or a common feature of the operating system that result in system hardening against techniques.' + } + 'M1030' = @{ + 'MitreTechniqueIDs' = @() + 'Mitigation' = 'Architect sections of the network to isolate critical systems, functions, or resources. Use physical and logical segmentation to prevent access to sensitive systems and information.' + } + 'M1031' = @{ + 'MitreTechniqueIDs' = @() + 'Mitigation' = 'Configure Network Intrusion Prevention systems to block malicious file signatures and file types at the network boundary.' + } + 'M1038' = @{ + 'MitreTechniqueIDs' = @() + 'Mitigation' = 'Block execution of code on a system.' + } + 'M1041' = @{ + 'MitreTechniqueIDs' = @() + 'Mitigation' = 'Use strong encryption mechanisms to protect sensitive data.' + } + 'M1042' = @{ + 'MitreTechniqueIDs' = @() + 'Mitigation' = 'Remove or deny access to unnecessary and potentially vulnerable software to prevent abuse by adversaries.' + } + 'M1057' = @{ + 'MitreTechniqueIDs' = @() + 'Mitigation' = 'Use a data loss prevention (DLP) strategy to categorize sensitive data, identify data formats indicative of personally identifiable information (PII), and restrict exfiltration of sensitive data.' + } + } + $CISAMitigations = @() + $KeysToRemove = @() + } + + Process { + foreach ($tactic in $Mappings.Keys) { + foreach ($technique in $Mappings[$tactic].Keys) { + $Mappings[$tactic][$technique].Keys | + #checks for each technique if there is a failed test + Where-Object { $Mappings[$tactic][$technique][$_] -eq [AuditInfoStatus]::False } | + ForEach-Object { + #if the mitigation from the failed test is in ihe mitigation from the cisa paper + if ($null -ne $json.$_.'Mitigation1' -and $CISAMitigationsFromPaper.Keys -contains $json.$_.'Mitigation1') { + #put the technique in the mapping (no doubles) + if ($CISAMitigationsFromPaper[$json.$_.'Mitigation1']['MitreTechniqueIDs'] -notcontains $technique) { + $CISAMitigationsFromPaper[$json.$_.'Mitigation1']['MitreTechniqueIDs'] += $technique + } + #put the mitigation in a separate array (no doubles) + if ($CISAMitigations -notcontains $json.$_.'Mitigation1') { + $CISAMitigations += $json.$_.'Mitigation1' + } + } + #if the mitigation from the failed test is in ihe mitigation from the cisa paper + if ($null -ne $json.$_.'Mitigation2' -and $CISAMitigationsFromPaper.Keys -contains $json.$_.'Mitigation2') { + #put the technique in the mapping (no doubles) + if ($CISAMitigationsFromPaper[$json.$_.'Mitigation2']['MitreTechniqueIDs'] -notcontains $technique) { + $CISAMitigationsFromPaper[$json.$_.'Mitigation2']['MitreTechniqueIDs'] += $technique + } + #put the mitigation in a separate array (no doubles) + if ($CISAMitigations -notcontains $json.$_.'Mitigation2') { + $CISAMitigations += $json.$_.'Mitigation2' + } + } + } + } + } + #write keys which where not in the sperat mitigation array in $KeysToRemove beacause you can't delete in a foreach over the object you want to delete from + $CISAMitigationsFromPaper.Keys | Where-Object { $CISAMitigations -notcontains $_ } | ForEach-Object { $KeysToRemove += $_ } + #delete the keys from $CISAMitigation from paper which were not in the sperate mitigation array + $KeysToRemove | ForEach-Object { $CISAMitigationsFromPaper.Remove($_) } + } + End { + return $CISAMitigationsFromPaper + } +} + +function ConvertTo-HtmlTable { + <# + .Synopsis + Generates a html table using the mapping keys of the tactics and techniques + It also adds the links to the table using the function "get-MitreLink" + and colours the cells + .Example + ConvertTo-HtmlTable $Mappings.map + + #> + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + $Mappings + ) + + htmlElement 'table' @{id = 'MITRETable' } { + htmlElement 'thead' @{id = 'MITREthead' } { + htmlElement 'tr' @{} { + foreach ($tactic in $Mappings.Keys) { + $url = get-MitreLink -type tactics -id $tactic + $TacticCount = Get-TacticCounter $tactic $Mappings + htmlElement 'td' @{} { + $tacticName = Get-MitreTacticName -TacticId $tactic + $link = htmlElement 'a' @{href = $url; target = "blank" } { "$tacticName" } + htmlElement 'p' @{} { $link + "`n" + "$TacticCount/" + $Mappings[$tactic].Count } + } + } + } + } + htmlElement 'tbody' @{id = 'MITREtbody' } { + htmlElement 'tr' @{} { + foreach ($tactic in $Mappings.Keys) { + htmlElement 'td' @{} { + foreach ($technique in $Mappings[$tactic].Keys) { + $successCounter = 0 + foreach ($id in $Mappings[$tactic][$technique].Keys) { + if ($Mappings[$tactic][$technique][$id] -eq [AuditInfoStatus]::True) { + $successCounter++ + } + } + $url = get-MitreLink -type techniques -id $technique + $color = Get-ColorValue $successCounter $Mappings[$tactic][$technique].Count + $categories = Get-MitreTechniqueCategories -TechniqueID $technique + htmlElement 'div' @{class = "MITRETechnique $categories"; style = "background-color: $color; background-clip: border-box" } { + htmlElement 'a' @{href = $url; target = "_blank"; class = "tooltip" } { "$technique" + htmlElement 'span' @{class = "tooltiptext" } { Get-MitreTechniqueName -TechniqueID $technique } + } + htmlElement 'span' @{} { ": $successCounter/" + $Mappings[$tactic][$technique].Count } + } + } + } + } + } + } + } +} + +function ConvertTo-HtmlCISA { + <# + .Synopsis + Generates a html table using the CISA Mitigation, Mitre Mitigation id and failed techniques + .Example + ConvertTo-HtmlCISA $CISAMitigations + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + $CISAMitigations + ) + #create CISA table + htmlElement 'table' @{id = 'CISATable' } { + #create table head with the column CISA Mitigation, MITRE Mitigation ID, MITRE Technique IDs + htmlElement 'thead' @{id = 'CISAthead' } { + htmlElement 'tr' @{} { + htmlElement 'th' @{class = 'CISAMitigationIDs' } { + 'ID' + } + htmlElement 'th' @{class = 'CISAMitigations' } { + 'Mitigation Description' + } + htmlElement 'th' @{class = 'CISAMitreTechniqueIDs' } { + 'caused Audit failures' + } + } + } + #fill the columns with the information from the $CISAMitigation map + htmlElement 'tbody' @{id = 'CISAtbody' } { + $KeyOrder = $CISAMitigations.GetEnumerator() | Sort-Object { $_.Value.MitreTechniqueIDs.Count } -Descending + $KeyOrder | ForEach-Object { + htmlElement 'tr' @{} { + htmlElement 'td' @{class = 'CISAMitigationIDs' } { + htmlElement 'a' @{href = $(get-MitreLink -type mitigations -id $_.Key); target = "_blank" } { + $_.Key + } + } + htmlElement 'td' @{class = 'CISAMitigations' } { + htmlElement 'a' @{} { + $CISAMitigations[$_.Key]['Mitigation'] + } + } + htmlElement 'td' @{class = 'CISAMitreTechniqueIDs' } { + $mitigationsList = $CISAMitigations[$_.Key]['MitreTechniqueIDs'] + for ($i = 0; $i -lt $mitigationsList.Length; $i++) { + htmlElement 'a' @{href = $(get-MitreLink -type techniques -id $mitigationsList[$i]); target = "_blank" } { + $mitigationsList[$i] + } + } + } + } + } + } + } +} + +function Get-ColorValue { + <# + .Synopsis + Compares two Integer variables returns true if equal, false if not + .Example + $colorValue = Get-ColorValue $successCounter $Mappings[$tactic][$technique].Count + #> + param ( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [int]$FirstValue, + + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [int]$SecondValue + ) + + if ($SecondValue -eq 0) { + $result = '#a7a7a7' + } + else { + $successPercentage = ($FirstValue / $SecondValue) + + switch ($successPercentage) { + 1 { $result = '#33cca6' } + { $_ -le 0.99 } { $result = '#52CC8F' } + { $_ -le 0.89 } { $result = '#70CC78' } + { $_ -le 0.79 } { $result = '#8FCC61' } + { $_ -le 0.69 } { $result = '#ADCC4A' } + { $_ -le 0.59 } { $result = '#CCCC33' } + { $_ -le 0.49 } { $result = '#CCA329' } + { $_ -le 0.39 } { $result = '#CC7A1F' } + { $_ -le 0.29 } { $result = '#CC5214' } + { $_ -le 0.19 } { $result = '#CC290A' } + { $_ -le 0.09 } { $result = '#cc0000' } + } + } + + return $result +} + +function Get-TacticCounter { + <# + .Synopsis + Counts the amount of successful techniques per tactic + .Example + $TacticCounter = Get-TacticCounter $tactic $Mappings + #> + param ( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [object]$tactic, + + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [object]$Mappings + ) + $TacticCount = 0 + foreach ($technique in $Mappings[$tactic].Keys) { + $successCounter = 0 + foreach ($id in $Mappings[$tactic][$technique].Keys) { + if ($Mappings[$tactic][$technique][$id] -eq [AuditInfoStatus]::True) { + $successCounter++ + } + if ($successCounter -eq $Mappings[$tactic][$technique].Count -And $successCounter -gt 0) { + $TacticCount++ + } + } + } + return $TacticCount +} + +#in the current state the function checks the cis version used for the mapping and used in the Save-ATAPHtmlReport +#but the versions don't match so the function prints the status in the HTML but doesn't block Merge-CisAuditsToMitreMap +function Compare-EqualCISVersions { + <# + .Synopsis + Returns a boolean, if the $ReportBasedOn and $MitreMappingCompatible Versions can be used together or not. + .Parameter $Title + The Title of the Report + .Parameter $ReportBasedOn + The BasedOn information from the report + .Parameter $MitreMappingCompatible + The Compatible CIS versions of the mitre mapping + .Example + Compare-EqualCISVersions -Title:$Title -ReportBasedOn:$ReportBasedOn -MitreMappingCompatible:$MitreMappingCompatible + #> + + param( + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] + $Title, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string[]] + $ReportBasedOn, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string[]] + $MitreMappingCompatible + ) + $os = [System.Environment]::OSVersion.Platform + + if (Test-CompatibleMitreReport -Title $Title -os $os) { + $ReportBasedOn = $ReportBasedOn | Where-Object { $_ -match 'CIS' } + return $($null -ne $ReportBasedOn -and $null -ne $MitreMappingCompatible -and $($ReportBasedOn -in $MitreMappingCompatible)) + } + return $false +} + +function Get-HtmlReportSection { + param( + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] + $Title, + + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [string] + $Description, + + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [alias('AuditInfos')] + [array] + $ConfigAudits, + + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [alias('Sections')] + [array] + $Subsections, + + [Parameter(Mandatory = $false)] + [string] + $Prefix + ) + + process { + $id = Convert-SectionTitleToHtmlId -Title ($Prefix + $Title) + $sectionStatus = Get-SectionStatus -ConfigAudits $ConfigAudits -Subsections $Subsections + $class = Get-HtmlClassFromStatus $sectionStatus + htmlElement 'section' @{} { + htmlElement 'h1' @{ id = $id } { + + + htmlElement 'span' @{ class = $class } { $Title } + htmlElement 'span' @{ class = 'sectionAction collapseButton' } { '-' } + htmlElement 'a' @{ href = '#toc'; class = 'sectionAction' } { + htmlElement 'span' @{ style = "font-size: 75%;" } { '↑' } + } + } + + if ($null -ne $Description) { + htmlElement 'p' @{} { $Description } + } + if ($null -ne $ConfigAudits) { + htmlElement 'table' @{ class = 'audit-info' } { + htmlElement 'tbody' @{} { + htmlElement 'tr' @{} { + foreach ($columnName in $AuditProperties.Name) { + htmlElement 'th' @{} { $columnName } + } + } + foreach ($configAudit in $ConfigAudits) { + $configAudit | Get-HtmlTableRow + } + } + } + } + if ($null -ne $Subsections) { + foreach ($subsection in $Subsections) { + $subsection | Get-HtmlReportSection -Prefix ($Prefix + $Title) + } + } + } + } +} + +function Get-ATAPHostInformation { + $unixOS = [System.Environment]::OSVersion.Platform -eq 'Unix' # returns 'Unix' on Linux and MacOS and 'Win32NT' on Windows, PS v6+ has builtin environment variable for this + if ($unixOS) { + return @{ + "Hostname" = hostname + "Operating System" = (Get-Content /etc/os-release | Select-String -Pattern '^PRETTY_NAME=\"(.*)\"$').Matches.Groups[1].Value + "Installation Language" = (($(locale) | Where-Object { $_ -match "LANG=" }) -split '=')[1] + "Kernel Version" = uname -r + "Free physical memory" = "{0:N1} GB" -f (( -split (Get-Content /proc/meminfo | Where-Object { $_ -match 'MemFree:' }))[1] / 1MB) + "Free disk space" = "{0:N1} GB" -f ((Get-PSDrive | Where-Object { $_.Name -eq '/' }).Free / 1GB) + "System Uptime" = Get-Uptime -p + "OS Architecture" = lscpu | awk '/Architecture/ {print $2}' + "System Manufacturer" = (dmidecode -t system)[6] | cut -d ':' -f 2 | xargs + "System SKU" = (dmidecode -t system)[12] | cut -d ':' -f 2 | xargs + "System Serialnumber" = (dmidecode -t system)[9] | cut -d ':' -f 2 | xargs + "BIOS Version" = dmidecode -s bios-version + } + } +} + +function Get-CompletionStatus { + param( + [string[]] + $Statuses, + + [array]$Sections + ) + + $totalCount = $Statuses.Count + $status = @{ + TotalCount = $totalCount + } + + #Total completion status + foreach ($value in $StatusValues) { + $count = ($Statuses | Where-Object { $_ -eq $value }).Count + $status[$value] = @{ + Count = $count + Percent = (100 * ($count / $totalCount)).ToString("0.00", [cultureinfo]::InvariantCulture) + } + } + + #Section Total Count + $sectionTotalCountHash = @{} + foreach ($section in $Sections) { + $sectionResult = $section | Select-ConfigAudit | Select-Object -ExpandProperty 'Status' + $totalSectionCount = 0 + foreach ($value in $StatusValues) { + $count = ($sectionResult | Where-Object { $_ -eq $value }).Count + $totalSectionCount += $count + } + $sectionTotalCountHash.Add($section.Title, $totalSectionCount) + } + #Counts the completion status for each section and each value. Also calculates the percentage. + $sectionCountHash = @{} + foreach ($section in $Sections) { + $sectionResult = $section | Select-ConfigAudit | Select-Object -ExpandProperty 'Status' + foreach ($value in $StatusValues) { + $count = ($sectionResult | Where-Object { $_ -eq $value }).Count + $sectionCountHash.Add($section.Title + $value + "Count", $count) + $percent = (100 * ($count / $sectionTotalCountHash[$section.Title])).ToString("0.00", [cultureinfo]::InvariantCulture) + $sectionCountHash.Add($section.Title + $value + "Percent", $percent) + } + } + return $status, $sectionTotalCountHash, $sectionCountHash +} + +function Get-OverallComplianceCSS { + [CmdletBinding()] + [OutputType([string])] + param( + $completionStatus + ) + + $css = "" + $percent = $completionStatus['True'].Percent / 1 + + if ($percent -gt 50) { + $degree = 180 + ((($percent - 50) / 1) * 3.6) + $css += ".donut-chart.chart .slice.one {clip: rect(0 200px 100px 0); -webkit-transform: rotate(90deg); transform: rotate(90deg);}" + $css += ".donut-chart.chart .slice.two {clip: rect(0 100px 200px 0); -webkit-transform: rotate($($degree)deg); transform: rotate($($degree)deg);}" + } + else { + $degree = 90 + ($percent * 3.6) + $css += ".donut-chart.chart .slice.one {clip: rect(0 200px 100px 0); -webkit-transform: rotate($($degree)deg); transform: rotate($($degree)deg);}" + $css += ".donut-chart.chart .slice.two {clip: rect(0 100px 200px 0); -webkit-transform: rotate(0deg); transform: rotate(0deg);}" + } + + $css += ".donut-chart.chart .chart-center span:after {content: `"$percent %`";}" + + return $css +} + +function Select-ConfigAudit { + param( + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [Alias('AuditInfos')] + [array] + $ConfigAudits, + + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [array] + $Subsections + ) + + process { + $results = @() + if ($null -ne $ConfigAudits) { + $results += $ConfigAudits + } + if ($null -ne $Subsections) { + foreach ($subsection in $Subsections) { + $results += $subsection | Select-ConfigAudit + } + } + return $results + } +} + +function Get-ATAPHtmlReport { + <# + .Synopsis + Generates an audit report in an html file. + .Description + The `Get-ATAPHtmlReport` cmdlet collects data from the current machine to generate an audit report. + .Parameter Path + Specifies the relative path to the file in which the report will be stored. + .Example + C:\PS> Get-ATAPHtmlReport -Path "MyReport.html" + #> + + [CmdletBinding()] + [OutputType([string])] + param( + [Parameter(Mandatory = $true)] + [string] + $Path, + + [Parameter(Mandatory = $false)] + [hashtable] + $HostInformation = (Get-ATAPHostInformation), + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] + $Title, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] + $ModuleName, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string] + $AuditorVersion, + + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [string[]] + $BasedOn, + + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [array] + $Sections, + + + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [string] + $LicenseStatus, + + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [RSFullReport[]] + $RSReport, + + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [FoundationReport] + $FoundationReport, + + [Parameter(Mandatory = $false)] + [switch] $RiskScore, + + [Parameter(Mandatory = $false)] + [switch] $MITRE, + + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [hashtable] + $hashtable_sha256, + + [switch] $ComplianceStatus, + + [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] + [SystemInformation] + $SystemInformation + ) + + process { + Write-Progress -Activity "Creating HTML report head" -Status "Progress:" -PercentComplete 0 + $allConfigResults = foreach ($section in $Sections) { $section | Select-ConfigAudit | Select-Object -ExpandProperty 'Status' } + $completionStatus, $sectionTotalCountHash, $sectionCountHash = Get-CompletionStatus -Statuses $allConfigResults -sections $Sections + + # HTML markup + + $head = htmlElement 'head' @{} { + htmlElement 'meta' @{ charset = 'UTF-8' } { } + htmlElement 'meta' @{ name = 'viewport'; content = 'width=device-width, initial-scale=1.0' } { } + htmlElement 'meta' @{ 'http-equiv' = 'X-UA-Compatible'; content = 'ie=edge' } { } + htmlElement 'title' @{} { "$Title [$(Get-Date)]" } + htmlElement 'style' @{} { + $cssPath = $ScriptRoot | Join-path -ChildPath "/report.css" + Get-Content $cssPath + Get-OverallComplianceCSS $completionStatus + } + htmlElement 'script' @{} { + $jsPath = $ScriptRoot | Join-path -ChildPath "/report.js" + Get-Content $jsPath + } + } + #Handles Release Date from Releases; Compares Release with this ATAP Version + Write-Progress -Activity "Creating HTML report body" -Status "Progress:" -PercentComplete 13 + $body = htmlElement 'body' @{onload = "startConditions()" } { + # Header + htmlElement 'div' @{ class = 'header content' } { + htmlElement 'div' @{ id = "logo" } { + htmlElement 'a' @{id = "companyLink"; href = "https://www.fb-pro.com/"; target = "_blank" } { + htmlElement 'h1' @{id = "companyName" } { "FB PRO GMBH" } + htmlElement 'p' @{id = "companySlogan" } { "System Hardening & Secure Configuration" } + } + } + htmlElement 'div' @{ id = "reportInformation" } { + htmlElement 'h1' @{} { $Title } + $datum = "{0:d}. {1} {2} {3:D2}:{4:D2}" -f (Get-Date).Day, (Get-Date).ToString("MMMM"), (Get-Date).Year, (Get-Date).Hour, (Get-Date).Minute + htmlElement 'div' @{} { "Generated on $($datum)" } + } + } + # Main section + htmlElement 'div' @{ class = 'main content' } { + htmlElement 'div' @{ class = 'host-information' } { + # Show compliance status + if ($ComplianceStatus) { + $sliceColorClass = Get-HtmlClassFromStatus 'True' + htmlElement 'div' @{ class = 'card' } { + htmlElement 'h2' @{} { 'Compliance status' } + htmlElement 'div' @{ class = 'donut-chart chart' } { + htmlElement 'div' @{ class = "slice one $sliceColorClass" } { } + htmlElement 'div' @{ class = "slice two $sliceColorClass" } { } + htmlElement 'div' @{ class = 'chart-center' } { htmlElement 'span' @{} { } } + } + } + } + + $os = [System.Environment]::OSVersion.Platform + + ### Risk Checks ### + if ($RiskScore) { + # Quantity + $TotalAmountOfRules = $completionStatus.TotalCount; + $AmountOfCompliantRules = 0; + $AmountOfNonCompliantRules = 0; + $None_Rules = 0; + foreach ($value in $StatusValues) { + if ($value -eq 'True') { + $AmountOfCompliantRules = $completionStatus[$value].Count + } + #exclude Rules, which are set to None, to make an independent calculation between Compliant and non Compliant + if ($value -eq 'None') { + $None_Rules = $completionStatus[$value].Count + } + if ($value -eq 'False') { + $AmountOfNonCompliantRules = $completionStatus[$value].Count + } + } + $TotalAmountOfRules = $TotalAmountOfRules - $None_Rules + if ($os -match "Win32NT" -and $Title -match "Win") { + # percentage of compliance quantity + $QuantityCompliance = [math]::round(($AmountOfCompliantRules / $TotalAmountOfRules) * 100, 2); + # Variables, which will be evaluated in report.js + htmlElement 'div' @{id = "AmountOfNonCompliantRules"; hidden="hidden"} { "$($AmountOfNonCompliantRules)" } + htmlElement 'div' @{id = "AmountOfCompliantRules"; hidden="hidden"} { "$($AmountOfCompliantRules)" } + htmlElement 'div' @{id = "TotalAmountOfRules"; hidden="hidden"} { "$($TotalAmountOfRules)" } + htmlElement 'div' @{id = "QuantityCompliance"; hidden="hidden"} { "$($QuantityCompliance)" } + + # Severity + htmlElement 'div' @{id = "TotalAmountOfSeverityRules"; hidden="hidden"} { "$($RSReport.RSSeverityReport.AuditInfos.Length)" } + $AmountOfFailedSeverityRules = 0; + foreach ($rule in $RSReport.RSSeverityReport.AuditInfos) { + if ($rule.Status -eq "False") { + $AmountOfFailedSeverityRules ++; + } + } + htmlElement 'div' @{id = "AmountOfFailedSeverityRules"; hidden="hidden"} { "$($AmountOfFailedSeverityRules)" } + } + } + + htmlElement 'div' @{id = 'navigationButtons' } { + htmlElement 'button' @{type = 'button'; class = 'navButton selectedNavButton'; id = 'summaryBtn'; onclick = "clickButton('1')" } { "Benchmark Compliance" } + htmlElement 'button' @{type = 'button'; class = 'navButton'; id = 'foundationDataBtn'; onclick = "clickButton('5')" } { "Security Base Data" } + if ($RiskScore -and ($os -match "Win32NT" -and $Title -match "Win")) { + htmlElement 'button' @{type = 'button'; class = 'navButton'; id = 'riskScoreBtn'; onclick = "clickButton('2')" } { "Risk Score" } + } + if ($MITRE) { + if (Test-CompatibleMitreReport -Title $Title -os $os) { + htmlElement 'button' @{type = 'button'; class = 'navButton'; id = 'MITREBtn'; onclick = "clickButton('6')" } { "MITRE ATT&CK" } + htmlElement 'button' @{type = 'button'; class = 'navButton'; id = 'CISABtn'; onclick = "clickButton('7')" } { "CISA Recommendations" } + } + } + htmlElement 'button' @{type = 'button'; class = 'navButton'; id = 'settingsOverviewBtn'; onclick = "clickButton('4')" } { "Hardening Settings" } + htmlElement 'button' @{type = 'button'; class = 'navButton'; id = 'referenceBtn'; onclick = "clickButton('3')" } { "About Us" } + } + + Write-Progress -Activity "Creating settings overview page" -Status "Progress:" -PercentComplete 25 + htmlElement 'div' @{class = 'tabContent'; id = 'settingsOverview'; style = 'display:none' } { + # Table of Contents + htmlElement 'h1' @{ id = 'toc' } { 'Hardening Settings' } + CreateHashTable + htmlElement 'h2' @{} { "Table Of Contents" } + htmlElement 'p' @{} { 'Click the link(s) below for quick access to a report section.' } + htmlElement 'ul' @{} { + foreach ($section in $Sections) { $section | Get-HtmlToc } + } + htmlElement 'h2' @{} { "Benchmark Details" } + + # Report Sections for hardening settings + foreach ($section in $Sections) { + $section | Get-HtmlReportSection + } + } + + Write-Progress -Activity "Creating summary page" -Status "Progress:" -PercentComplete 38 + #This div hides/reveals the whole summary section + htmlElement 'div' @{class = 'tabContent'; id = 'summary' } { + # Host information + htmlElement 'h1' @{} { 'Benchmark Compliance' } + htmlElement 'div' @{style = "float: left;" } { + htmlElement 'p' @{} { + "Modules:" + htmlElement 'ul' @{} { + htmlElement 'div' @{} { "ATAPAuditor version $AuditorVersion" } + htmlElement 'div' @{} { "ATAPHtmlReport version $ModuleVersion" } + } + } + htmlElement 'p' @{} { + "Test baseline:" + htmlElement 'ul' @{} { + foreach ($item in $BasedOn) { + htmlElement 'li' @{} { $item } + } + } + htmlElement 'div' @{} { + "Does your system show low benchmark compliance? Check out our hardening solutions." + } + } + } + htmlElement 'div' @{id = 'riskMatrixSummaryArea' } { + if ($RiskScore -and ($os -match "Win32NT" -and $Title -match "Win")) { + htmlElement 'h2' @{id = 'CurrentRiskScore' } { "Current Risk Score of tested System: " } + htmlElement 'h3' @{} { 'For further information, please head to the tab "Risk Score".' } + htmlElement 'div' @{id = 'riskMatrixSummary' } { + htmlElement 'div' @{id = 'dotSummaryTab'; style = 'display:none'} {} + htmlElement 'div' @{id = 'severity' } { + htmlElement 'p' @{id = 'severityArea' } { 'Severity' } + } + htmlElement 'div' @{id = 'quantity' } { + htmlElement 'p' @{id = 'quantityArea' } { 'Quantity' } + } + htmlElement 'div' @{id = 'severityCritical' } { "Critical" } + htmlElement 'div' @{id = 'severityHigh' } { "High" } + htmlElement 'div' @{id = 'severityMedium' } { "Medium" } + htmlElement 'div' @{id = 'severityLow' } { "Low" } + + htmlElement 'div' @{id = 'quantityCritical' } { "Critical" } + htmlElement 'div' @{id = 'quantityHigh' } { "High" } + htmlElement 'div' @{id = 'quantityMedium' } { "Medium" } + htmlElement 'div' @{id = 'quantityLow' } { "Low" } + + #colored areas + htmlElement 'div' @{id = 'critical_low' } {} + htmlElement 'div' @{id = 'high_low' } {} + htmlElement 'div' @{id = 'medium_low' } {} + htmlElement 'div' @{id = 'low_low' } {} + + htmlElement 'div' @{id = 'critical_medium' } {} + htmlElement 'div' @{id = 'high_medium' } {} + htmlElement 'div' @{id = 'medium_medium' } {} + htmlElement 'div' @{id = 'low_medium' } {} + + htmlElement 'div' @{id = 'critical_high' } {} + htmlElement 'div' @{id = 'high_high' } {} + htmlElement 'div' @{id = 'medium_high' } {} + htmlElement 'div' @{id = 'low_high' } {} + + htmlElement 'div' @{id = 'critical_critical' } {} + htmlElement 'div' @{id = 'high_critical' } {} + htmlElement 'div' @{id = 'medium_critical' } {} + htmlElement 'div' @{id = 'low_critical' } {} + } + } + else { + if ($RiskScore) { + htmlElement 'h2' @{id = 'CurrentRiskScore' } { "Current Risk Score of tested System:" } + htmlElement 'h2' @{id = 'invalidOS' } { "N/A" } + htmlElement 'h3' @{} { 'Risk Score calculation implemented for Microsoft Windows OS for now.' } + htmlElement 'div' @{id = 'riskMatrixSummary' } { + htmlElement 'div' @{id = 'severity' } { + htmlElement 'p' @{id = 'severityArea' } { 'Severity' } + } + htmlElement 'div' @{id = 'quantity' } { + htmlElement 'p' @{id = 'quantityArea' } { 'Quantity' } + } + htmlElement 'div' @{id = 'severityCritical' } { "Critical" } + htmlElement 'div' @{id = 'severityHigh' } { "High" } + htmlElement 'div' @{id = 'severityMedium' } { "Medium" } + htmlElement 'div' @{id = 'severityLow' } { "Low" } + + htmlElement 'div' @{id = 'quantityCritical' } { "Critical" } + htmlElement 'div' @{id = 'quantityHigh' } { "High" } + htmlElement 'div' @{id = 'quantityMedium' } { "Medium" } + htmlElement 'div' @{id = 'quantityLow' } { "Low" } + + #colored areas + htmlElement 'div' @{id = 'critical_low' } {} + htmlElement 'div' @{id = 'high_low' } {} + htmlElement 'div' @{id = 'medium_low' } {} + htmlElement 'div' @{id = 'low_low' } {} + + htmlElement 'div' @{id = 'critical_medium' } {} + htmlElement 'div' @{id = 'high_medium' } {} + htmlElement 'div' @{id = 'medium_medium' } {} + htmlElement 'div' @{id = 'low_medium' } {} + + htmlElement 'div' @{id = 'critical_high' } {} + htmlElement 'div' @{id = 'high_high' } {} + htmlElement 'div' @{id = 'medium_high' } {} + htmlElement 'div' @{id = 'low_high' } {} + + htmlElement 'div' @{id = 'critical_critical' } {} + htmlElement 'div' @{id = 'high_critical' } {} + htmlElement 'div' @{id = 'medium_critical' } {} + htmlElement 'div' @{id = 'low_critical' } {} + } + } + } + } + + # Benchmark compliance + htmlElement 'h1' @{ style = 'clear:both;' } {} + htmlElement 'p' @{} { + 'A total of {0} tests have been executed.' -f @( + $completionStatus.TotalCount + ) + } + + # Status percentage gauge + htmlElement 'div' @{ class = 'gauge' } { + foreach ($value in $StatusValues) { + $count = $completionStatus[$value].Count + if($count -gt 0){ + $htmlClass = Get-HtmlClassFromStatus $value + $percent = $completionStatus[$value].Percent + + htmlElement 'div' @{ + class = "gauge-meter $htmlClass" + style = "--weight: $count;" #fills the gauge bar to some percent + title = "$value $count test(s), $($percent)%" + } { } + } + } + } + htmlElement 'ol' @{ class = 'gauge-info' } { + foreach ($value in $StatusValues) { + $count = $completionStatus[$value].Count + $htmlClass = Get-HtmlClassFromStatus $value + $percent = $completionStatus[$value].Percent + + htmlElement 'li' @{ class = 'gauge-info-item' } { + htmlElement 'span' @{ class = "auditstatus $htmlClass" } { "$($percent)% $value" } + "
(Tests: $count)" + } + } + + } + # Sections + foreach ($section in $Sections) { + htmlElement 'h2' @{ style = 'clear:both; margin-top: 0;' } { $section.Title } + htmlElement 'p' @{} { + 'A total of {0} tests have been executed in section {1}.' -f @( + $sectionTotalCountHash[$section.Title] + $section.Title + ) + } + + # Status percentage gauge for sections + htmlElement 'div' @{ class = 'gauge' } { + foreach ($value in $StatusValues) { + $count = $sectionCountHash[$section.Title + $value + "Count"] + if ($count -gt 0) { + $htmlClass = Get-HtmlClassFromStatus $value + $percent = $sectionCountHash[$section.Title + $value + "Percent"] + htmlElement 'div' @{ + class = "gauge-meter $htmlClass" + style = "--weight: $count;" #fills the gauge bar to some percent + title = "$value $count test(s), $($percent)%" + } { } + } + } + } + htmlElement 'ol' @{ class = 'gauge-info' } { + foreach ($value in $StatusValues) { + $count = $sectionCountHash[$section.Title + $value + "Count"] + $htmlClass = Get-HtmlClassFromStatus $value + $percent = $sectionCountHash[$section.Title + $value + "Percent"] + + htmlElement 'li' @{ class = 'gauge-info-item' } { + htmlElement 'span' @{ class = "auditstatus $htmlClass" } { "$($percent)% $value" } + "
(Tests: $count)" + } + } + } + } + } + + Write-Progress -Activity "Creating foundation data page" -Status "Progress:" -PercentComplete 50 + htmlElement 'div' @{class = 'tabContent'; id = 'foundationData'; style = 'display:none' } { + #Tab: Foundation Data (Only works for Windows OS!) + htmlElement 'h1' @{} { "Security Base Data" } + htmlElement 'div' @{id = "testGrid" } { + htmlElement 'div' @{style = "grid-column-start: 1; grid-column-end: 2; grid-row-start: 1; grid-row-end: 2; font-size: 23px; font-weight: bold; border: 0; padding-top: 0px;" } { "System Information" } + htmlElement 'div' @{style = "grid-column-start: 1; grid-column-end: 3; grid-row-start: 2; grid-row-end: 3; font-weight: bold; background-color: lightgray;" } { "Software Information" } + htmlElement 'div' @{style = "grid-column-start: 4; grid-column-end: 6; grid-row-start: 2; grid-row-end: 3; font-weight: bold; background-color: lightgray;" } { "Hardware Information" } + + $systeminfo_array = @( + @{ colStart = 1; rowstart = 3; + name = "Hostname" + value = $($SystemInformation.SoftwareInformation.Hostname)} + @{ colStart = 1; rowstart = 4; + name = "System Uptime" + value = $($SystemInformation.SoftwareInformation.SystemUptime)} + @{ colStart = 1; rowstart = 5; + name = "Operating System" + value = $($SystemInformation.SoftwareInformation.OperatingSystem)} + @{ colStart = 1; rowstart = 6; + name = "Build Number" + value = $($SystemInformation.SoftwareInformation.BuildNumber)} + @{ colStart = 1; rowstart = 7; + name = "OS Architecture" + value = $($SystemInformation.SoftwareInformation.OSArchitecture)} + @{ colStart = 1; rowstart = 8; + name = "License Status" + value = $($SystemInformation.SoftwareInformation.LicenseStatus)} + @{ colStart = 1; rowstart = 9; + name = "Installation Language" + value = $($SystemInformation.SoftwareInformation.InstallationLanguage)} + @{ colStart = 1; rowstart = 10; + name = "Domain role" + value = $($SystemInformation.SoftwareInformation.DomainRole)} + + @{ colStart = 4; rowstart = 3; + name = "System Manufacturer" + value = $($SystemInformation.HardwareInformation.SystemManufacturer)} + @{ colStart = 4; rowstart = 4; + name = "System SKU" + value = $($SystemInformation.HardwareInformation.SystemSKU) } + @{ colStart = 4; rowstart = 5; + name = "System Model" + value = $($SystemInformation.HardwareInformation.SystemModel)} + @{ colStart = 4; rowstart = 6; + name = "System Serialnumber" + value = $($SystemInformation.HardwareInformation.SystemSerialnumber)} + @{ colStart = 4; rowstart = 7; + name = "BIOS Version" + value = $($SystemInformation.HardwareInformation.BIOSVersion)} + @{ colStart = 4; rowstart = 8; + name = "Free disk space (C:)" + value = $($SystemInformation.HardwareInformation.FreeDiskSpace)} + @{ colStart = 4; rowstart = 9; + name = "Free physical memory" + value = $($SystemInformation.HardwareInformation.FreePhysicalMemory)} + ) + + for ($i = 0; $i -lt $systeminfo_array.Length; $i++) { + $grayBackground = "" + if($i%2 -eq 0){ + $grayBackground = "background-color: var(--color-light-gray);" + } + htmlElement 'div' @{style = "grid-column-start: $($systeminfo_array[$i].colStart+0); grid-column-end: $($systeminfo_array[$i].colStart+1); grid-row-start: $($systeminfo_array[$i].rowStart); grid-row-end: $($systeminfo_array[$i].rowStart+1); $($grayBackground) font-weight: bold;" } { "$($systeminfo_array[$i].name)" } + htmlElement 'div' @{style = "grid-column-start: $($systeminfo_array[$i].colStart+1); grid-column-end: $($systeminfo_array[$i].colStart+2); grid-row-start: $($systeminfo_array[$i].rowStart); grid-row-end: $($systeminfo_array[$i].rowStart+1); $($grayBackground)" } { "$($systeminfo_array[$i].value)" } + } + + + + # htmlElement 'div' @{style = "grid-column-start: 4; grid-column-end: 5; grid-row-start: 3; grid-row-end: 4; background-color: #efefef; font-weight: bold;" } { "System Manufacturer" } + # htmlElement 'div' @{style = "grid-column-start: 5; grid-column-end: 6; grid-row-start: 3; grid-row-end: 4; background-color: #efefef;" } { $($SystemInformation.HardwareInformation.SystemManufacturer) } + + # htmlElement 'div' @{style = "grid-column-start: 4; grid-column-end: 5; grid-row-start: 4; grid-row-end: 5; font-weight: bold;" } { "System SKU" } + # htmlElement 'div' @{style = "grid-column-start: 5; grid-column-end: 6; grid-row-start: 4; grid-row-end: 5;" } { $($SystemInformation.HardwareInformation.SystemSKU) } + + # htmlElement 'div' @{style = "grid-column-start: 4; grid-column-end: 5; grid-row-start: 5; grid-row-end: 6; background-color: #efefef; font-weight: bold;" } { "System Model" } + # htmlElement 'div' @{style = "grid-column-start: 5; grid-column-end: 6; grid-row-start: 5; grid-row-end: 6; background-color: #efefef;" } { $($SystemInformation.HardwareInformation.SystemModel) } + + # htmlElement 'div' @{style = "grid-column-start: 4; grid-column-end: 5; grid-row-start: 6; grid-row-end: 7; font-weight: bold;" } { "System Serialnumber" } + # htmlElement 'div' @{style = "grid-column-start: 5; grid-column-end: 6; grid-row-start: 6; grid-row-end: 7;" } { $($SystemInformation.HardwareInformation.SystemSerialnumber) } + + # htmlElement 'div' @{style = "grid-column-start: 4; grid-column-end: 5; grid-row-start: 7; grid-row-end: 8; background-color: #efefef; font-weight: bold;" } { "BIOS Version" } + # htmlElement 'div' @{style = "grid-column-start: 5; grid-column-end: 6; grid-row-start: 7; grid-row-end: 8; background-color: #efefef;" } { $($SystemInformation.HardwareInformation.BIOSVersion) } + + # htmlElement 'div' @{style = "grid-column-start: 4; grid-column-end: 5; grid-row-start: 8; grid-row-end: 9; font-weight: bold;" } { "Free disk space (C:)" } + # htmlElement 'div' @{style = "grid-column-start: 5; grid-column-end: 6; grid-row-start: 8; grid-row-end: 9;" } { $($SystemInformation.HardwareInformation.FreeDiskSpace) } + + # htmlElement 'div' @{style = "grid-column-start: 4; grid-column-end: 5; grid-row-start: 9; grid-row-end: 10; background-color: #efefef; font-weight: bold;" } { "Free physical memory" } + # htmlElement 'div' @{style = "grid-column-start: 5; grid-column-end: 6; grid-row-start: 9; grid-row-end: 10; background-color: #efefef;" } { $($SystemInformation.HardwareInformation.FreePhysicalMemory) } + + + + + # htmlElement 'div' @{style = "grid-column-start: 1; grid-column-end: 2; grid-row-start: 3; grid-row-end: 4; background-color: #efefef; font-weight: bold;" } { "Hostname" } + # htmlElement 'div' @{style = "grid-column-start: 2; grid-column-end: 3; grid-row-start: 3; grid-row-end: 4; background-color: #efefef;" } { $($SystemInformation.SoftwareInformation.Hostname) } + + # htmlElement 'div' @{style = "grid-column-start: 1; grid-column-end: 2; grid-row-start: 4; grid-row-end: 5; font-weight: bold;" } { "System Uptime" } + # htmlElement 'div' @{style = "grid-column-start: 2; grid-column-end: 3; grid-row-start: 4; grid-row-end: 5;" } { $($SystemInformation.SoftwareInformation.SystemUptime) } + + # htmlElement 'div' @{style = "grid-column-start: 1; grid-column-end: 2; grid-row-start: 5; grid-row-end: 6; background-color: #efefef; font-weight: bold;" } { "Operating System" } + # htmlElement 'div' @{style = "grid-column-start: 2; grid-column-end: 3; grid-row-start: 5; grid-row-end: 6; background-color: #efefef;" } { $($SystemInformation.SoftwareInformation.OperatingSystem) } + + # htmlElement 'div' @{style = "grid-column-start: 1; grid-column-end: 2; grid-row-start: 6; grid-row-end: 7; font-weight: bold;" } { "Build Number" } + # htmlElement 'div' @{style = "grid-column-start: 2; grid-column-end: 3; grid-row-start: 6; grid-row-end: 7;" } { $($SystemInformation.SoftwareInformation.BuildNumber) } + + # htmlElement 'div' @{style = "grid-column-start: 1; grid-column-end: 2; grid-row-start: 7; grid-row-end: 8; background-color: #efefef; font-weight: bold;" } { "OS Architecture" } + # htmlElement 'div' @{style = "grid-column-start: 2; grid-column-end: 3; grid-row-start: 7; grid-row-end: 8; background-color: #efefef;" } { $($SystemInformation.SoftwareInformation.OSArchitecture) } + + # htmlElement 'div' @{style = "grid-column-start: 1; grid-column-end: 2; grid-row-start: 8; grid-row-end: 9; font-weight: bold;" } { "License Status" } + # htmlElement 'div' @{style = "grid-column-start: 2; grid-column-end: 3; grid-row-start: 8; grid-row-end: 9;" } { $($SystemInformation.SoftwareInformation.LicenseStatus) } + + # htmlElement 'div' @{style = "grid-column-start: 1; grid-column-end: 2; grid-row-start: 9; grid-row-end: 10; background-color: #efefef; font-weight: bold;" } { "Installation Language" } + # htmlElement 'div' @{style = "grid-column-start: 2; grid-column-end: 3; grid-row-start: 9; grid-row-end: 10; background-color: #efefef;" } { $($SystemInformation.SoftwareInformation.InstallationLanguage) } + + # htmlElement 'div' @{style = "grid-column-start: 1; grid-column-end: 2; grid-row-start: 10; grid-row-end: 11; font-weight: bold;" } { "Domain role" } + # htmlElement 'div' @{style = "grid-column-start: 2; grid-column-end: 3; grid-row-start: 10; grid-row-end: 11;" } { $($SystemInformation.SoftwareInformation.DomainRole) } + } + # htmlElement 'div' @{id="systemData"} { + # } + if ([System.Environment]::OSVersion.Platform -ne 'Unix') { + htmlElement 'h2' @{} { "Table Of Contents" } + htmlElement 'p' @{} { 'Use below links to jump to a specific report section.' } + htmlElement 'ul' @{} { + foreach ($section in $FoundationReport.Sections) { $section | Get-HtmlToc } + } + htmlElement 'h2' @{} { "Details" } + # Report Sections + foreach ($section in $FoundationReport.Sections) { $section | Get-HtmlReportSection } + } + } + + if ($RiskScore) { + Write-Progress -Activity "Creating risk score page" -Status "Progress:" -PercentComplete 63 + htmlElement 'div' @{class = 'tabContent'; id = 'riskScore' } { + htmlElement 'h1'@{} { "Risk Score" } + htmlElement 'p'@{} { "The risk score provides a quick overview of how secure the system is configured. This is made up of the areas `"Severity`" and `"Quantity`". The higher risk is used as the overall risk." } + htmlElement 'h2' @{id = 'CurrentRiskScoreRS' } { "Current Risk Score of tested System: " } + + htmlElement 'div' @{id = 'riskMatrixContainer' } { + htmlElement 'div' @{id = 'dotRiskScoreTab' } {} + htmlElement 'div' @{id = 'severity' } { + htmlElement 'p' @{id = 'severityArea' } { 'Severity' } + } + htmlElement 'div' @{id = 'quantity' } { + htmlElement 'p' @{id = 'quantityArea' } { 'Quantity' } + } + htmlElement 'div' @{id = 'severityCritical' } { "Critical" } + htmlElement 'div' @{id = 'severityHigh' } { "High" } + htmlElement 'div' @{id = 'severityMedium' } { "Medium" } + htmlElement 'div' @{id = 'severityLow' } { "Low" } + + htmlElement 'div' @{id = 'quantityCritical' } { "Critical" } + htmlElement 'div' @{id = 'quantityHigh' } { "High" } + htmlElement 'div' @{id = 'quantityMedium' } { "Medium" } + htmlElement 'div' @{id = 'quantityLow' } { "Low" } + + #colored areas + htmlElement 'div' @{id = 'critical_low' } {} + htmlElement 'div' @{id = 'high_low' } {} + htmlElement 'div' @{id = 'medium_low' } {} + htmlElement 'div' @{id = 'low_low' } {} + + htmlElement 'div' @{id = 'critical_medium' } {} + htmlElement 'div' @{id = 'high_medium' } {} + htmlElement 'div' @{id = 'medium_medium' } {} + htmlElement 'div' @{id = 'low_medium' } {} + + htmlElement 'div' @{id = 'critical_high' } {} + htmlElement 'div' @{id = 'high_high' } {} + htmlElement 'div' @{id = 'medium_high' } {} + htmlElement 'div' @{id = 'low_high' } {} + + htmlElement 'div' @{id = 'critical_critical' } {} + htmlElement 'div' @{id = 'high_critical' } {} + htmlElement 'div' @{id = 'medium_critical' } {} + htmlElement 'div' @{id = 'low_critical' } {} + } + + htmlElement 'div' @{id = 'calculationTables' } { + htmlElement 'h3' @{class = 'calculationTablesText' } { "Risk Score Calculation" } + htmlElement 'p' @{class = 'calculationTablesText' } { "Risk Score calculation is based on the quantitative amount of compliant rules and the severity of incompliant checks." } + htmlElement 'p' @{class = 'calculationTablesText' } { "Note: Quantity is calculated by dividing all compliant rules with the total number (minus none-compliant) of checks." } + htmlElement 'table' @{id = 'quantityTable' } { + htmlElement 'tr' @{} { + htmlElement 'th' @{} { 'Compliance to Benchmarks (Quantity)' } + htmlElement 'th' @{} { 'Risk Assessment' } + } + htmlElement 'tr' @{} { + htmlElement 'td' @{} { 'More than 80%' } + htmlElement 'td' @{} { 'Low' } + } + htmlElement 'tr' @{} { + htmlElement 'td' @{} { 'Between 65% and 80%' } + htmlElement 'td' @{} { 'Medium' } + } + htmlElement 'tr' @{} { + htmlElement 'td' @{} { 'Between 50% and 65%' } + htmlElement 'td' @{} { 'High' } + } + htmlElement 'tr' @{} { + htmlElement 'td' @{} { 'Less than 50%' } + htmlElement 'td' @{} { 'Critical' } + } + } + + htmlElement 'table' @{id = 'severityTable' } { + htmlElement 'tr' @{} { + htmlElement 'th' @{} { 'Compliance to Benchmarks (Severity)' } + htmlElement 'th' @{} { 'Risk Assessment' } + } + htmlElement 'tr' @{} { + htmlElement 'td' @{} { 'All critical settings compliant' } + htmlElement 'td' @{} { 'Low' } + } + htmlElement 'tr' @{} { + htmlElement 'td' @{} { '1 or more incompliant setting(s)' } + htmlElement 'td' @{} { 'Critical' } + } + } + } + + + htmlElement 'div' @{id = "severityCompliance" } { + htmlElement 'h2' @{} { 'Details' } + htmlElement 'p' @{id = "complianceStatus" } { 'Table Of Severity Rules' } + htmlElement 'span' @{class = "sectionAction collapseButton"; id = "severityComplianceCollapse" } { "-" } + htmlElement 'table' @{id = 'severityDetails' } { + htmlElement 'tr' @{} { + htmlElement 'th' @{} { 'Id' } + htmlElement 'th' @{} { 'Task' } + htmlElement 'th' @{} { 'Status' } + htmlElement 'th' @{} { 'Severity' } + } + foreach ($info in $RSReport.RSSeverityReport.AuditInfos) { + htmlElement 'tr' @{} { + htmlElement 'td' @{} { "$($info.Id)" } + htmlElement 'td' @{} { "$($info.Task)" } + htmlElement 'td' @{} { + if ($info.Status -eq 'False') { + htmlElement 'span' @{class = "severityResultFalse" } { + "$($info.Status)" + } + } + elseif ($info.Status -eq 'True') { + htmlElement 'span' @{class = "severityResultTrue" } { + "$($info.Status)" + } + } + elseif ($info.Status -eq 'None') { + htmlElement 'span' @{class = "severityResultNone" } { + "$($info.Status)" + } + } + elseif ($info.Status -eq 'Warning') { + htmlElement 'span' @{class = "severityResultWarning" } { + "$($info.Status)" + } + } + elseif ($info.Status -eq 'Error') { + htmlElement 'span' @{class = "severityResultError" } { + "$($info.Status)" + } + } + } + htmlElement 'td' @{} { + htmlElement 'p' @{style = "margin: 5px auto;" } { "Critical" } + } + } + } + } + } + # 'Test for AuditInfo: ' + $RSReport.RSSeverityReport.TestTable + } + } + + if ($MITRE) { + if (Test-CompatibleMitreReport -Title $Title -os $os) { + Write-Progress -Activity "Creating mitre heatmap page" -Status "Progress:" -PercentComplete 75 + + $Mappings = $Sections | + Where-Object { $_.Title -eq "CIS Benchmarks" -or $_.Title -eq "CIS Stand-alone Benchmarks" } | + ForEach-Object { return $_.SubSections } | + ForEach-Object { return $_.AuditInfos } | + Merge-CisAuditsToMitreMap + + htmlElement 'div' @{class = 'tabContent'; id = 'MITRE' } { + htmlElement 'h1'@{} { "MITRE ATT&CK" } + htmlElement 'p'@{} { 'To get a quick overview of how good your system is hardened in terms of the MITRE ATT&CK Framework we made a heatmap.' } + htmlElement 'p' @{id = 'Tip' } { 'Tip: Hover over the MITRE IDs to get a quick information to each Technique' } + htmlElement 'h2'@{} { "Version of CIS in MITRE Mapping and tests" } + htmlElement 'p'@{} { $(Get-MitreMappingMetaData Version) + "." } + htmlElement 'p'@{} { "Based on: " + $(Get-MitreMappingMetaData BasedOn) + "." } + $MitreMappingCompatible = Get-MitreMappingMetaData Compatible + if (-not $(Compare-EqualCISVersions -Title:$Title -ReportBasedOn:$BasedOn -MitreMappingCompatible:$MitreMappingCompatible)) { + Write-Warning "The CIS version used for the MITRE mapping doesn't match with the CIS version used for the tests. The Mitre heatmap will still be generated but might contain false information." + htmlElement 'p'@{style = "font-size: 1.2em; color: red;" } { "The CIS version used for the MITRE mapping doesn't match with the CIS version used for the tests." } + } + htmlElement 'h2' @{} { 'Explanation of the cell colors' } + + htmlElement 'div' @{class = 'square-container' } { + $color_S = Get-ColorValue 1 1 + htmlElement 'div' @{class = 'square'; style = "background: $color_S" } {} + htmlElement 'div'@{} { '= 100% of the tests were successful, the system is protected in the best possible way' } + } + + htmlElement 'div' @{class = 'square-container' } { + $color_F = Get-ColorValue 0 1 + htmlElement 'div' @{class = 'square'; style = "background: $color_F" } {} + htmlElement 'div'@{} { '= 0% of the tests were successful, consider looking into possibilities to harden your system regarding this tactic / technique' } + } + + htmlElement 'div' @{class = 'square-container' } { + $color_S = Get-ColorValue 1 1 + $color_F = Get-ColorValue 0 1 + htmlElement 'div' @{class = 'square'; style = "background: linear-gradient($color_S,$color_F)" } {} + htmlElement 'div'@{} { '= the color gradient moves in 10% steps. The greener the cell, the more tests were successful' } + } + + htmlElement 'div' @{class = 'square-container' } { + $color_E = Get-ColorValue 1 0 + htmlElement 'div' @{class = 'square'; style = "background: $color_E" } {} + htmlElement 'div'@{} { '= No tests available yet' } + } + + htmlElement 'h2' @{} { "Filters" } + + htmlElement 'label' @{} { + "Hide techniques that are performed outside of enterprise defenses and controls:" + htmlElement 'input' @{type = "checkbox"; id = "mitreFilterCheckbox"; onchange = "hideMitreTechniques(this, '.orgMeasure')" } {} + } + + htmlElement 'p' @{} { + htmlElement 'label' @{} { + "Hide techniques that cannot be easily mitigated with preventive controls:" + htmlElement 'input' @{type = "checkbox"; id = "noEasyMitigationCheckbox"; onchange = "hideMitreTechniques(this, '.noEasyMitigation')" } {} + } + } + + htmlElement 'p' @{} { + htmlElement 'label' @{} { + "Display only techniques related to the attack vector 'E-Mail'" + htmlElement 'input' @{type = "checkbox"; id = "mailFilterCheckbox"; onchange = "hideMitreTechniques(this, '.MITRETechnique:not(.mailVector)')" } {} + } + } + + htmlElement 'h2' @{} { "Current ATT&CK heatmap on tested System" } + + ConvertTo-HtmlTable $Mappings.map + } + htmlElement 'div' @{class = 'tabContent'; id = 'CISA' } { + htmlElement 'h1'@{} { "CISA Recommendations" } + htmlElement 'p' @{} { + "This table shows the top mitigations, that help against the most used attack techniques. + Implementing these mitigations has the biggest impact on the overall security of the system. + The table is based on the Information from CISAs " + htmlElement 'a' @{href = "https://www.cisa.gov/sites/default/files/publications/RVA_INFOGRAPHIC_508c.pdf"; target = "_blank" } { + "Risk and Vulnerability Assessment (RVA) mapped to the MITRE ATT&CK Framework." + } + "Additionally, the table is sorted based on the number of audits that failed but could be prevented by a given mitigation." + } + htmlElement 'p'@{} { 'The table presents three columns: The first column lists the mitigations recommended by CISA, the second column contains the corresponding mitigation IDs from MITRE, and the third column shows the techniques that have at least one CISA-recommended mitigation and have experienced at least one test failure.' } + htmlElement 'h1'@{} { 'Mitigation for top techniques' } + + $CISAMitigations = $Mappings.Map | Get-MitigationsFromFailedTests + ConvertTo-HtmlCISA $CISAMitigations + } + } + else { + Write-Warning "Mitre Heatmap can only be used on a Windows System together with `"Microsoft Windows 10`", `"Microsoft Windows 10 Stand-alone`", `"Microsoft Windows 11`", `"Microsoft Windows 11 Stand-alone`", `"Microsoft Windows Server 2019`" or `"Microsoft Windows Server 2022`". The Mitre Heatmap will not be generated" + } + } + + Write-Progress -Activity "Creating references page" -Status "Progress:" -PercentComplete 83 + htmlElement 'div' @{class = 'tabContent'; id = 'references'; style = 'display:none' } { + + + htmlElement 'h1' @{} { "About us" } + + # Flex-Container + htmlElement 'div' @{class = 'columns-container' } { + + # LEFT COLUMN + htmlElement 'div' @{class = 'left-column' } { + htmlElement 'h2' @{} { "What makes FB Pro GmbH different" } + + htmlElement 'h3' @{} { "What do we want?" } + htmlElement 'p' @{} { + "Protect our customers' data and information - and thus implicitly contribute to the safe use of the Internet." + } + + htmlElement 'h3' @{} { "How do we achieve this?" } + htmlElement 'p' @{} { + "We implement in-depth IT security for our customers. Our approach always focuses on state-of-the-art technology that is highly efficient and automated." + } + + htmlElement 'h3' @{} { "What is system hardening?" } + htmlElement 'p' @{} { "The following video provides concise answers to questions such as:" } + htmlElement 'ul' @{class = 'hardening-ul' } { + htmlElement 'li' @{} { "What does System Hardening mean?" } + htmlElement 'li' @{} { "How does System Hardening work?" } + htmlElement 'li' @{} { "Why is System Hardening so important?" } + } + htmlElement 'p' @{style = 'font-style: italic;' } { + "If you cannot see the video below, please check your browser settings to allow loading content from external sources. + Alternatively, you can watch the video " + htmlElement 'a' @{href = "https://www.youtube.com/watch?v=jbI19FwnBKY"; target = "_blank" } { "here" + } + } + + htmlElement 'div' @{class = 'video-wrapper' } { + htmlElement 'iframe' @{ + src = "https://www.youtube-nocookie.com/embed/jbI19FwnBKY?si=_p7JoaNAkxRB0HIL" + title = "YouTube video player" + frameborder = "0" + allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + referrerpolicy = "strict-origin-when-cross-origin" + allowfullscreen = "" + } {} + } + } + + # RIGHT COLUMN + htmlElement 'div' @{class = 'right-column' } { + + htmlElement 'h2' @{} { "Check out our solutions" } + # Flex-Container for the products + htmlElement 'div' @{class = 'product-block' } { + # Flex-Container for each product item (order in column and centered) + htmlElement 'div' @{class = 'product-item ' } { + htmlElement 'h3'@{} { "Enforce Administrator" } + htmlElement 'a' @{href = "https://www.fb-pro.com/enforce-administrator-product/"; target = "_blank" } { + htmlElement 'img' @{ + src = $Settings.EA + alt = "Enforce Administrator" + style = "width: 125px; height: 200px;" + } {} + } + } + htmlElement 'div' @{class = 'product-item ' } { + htmlElement 'h3'@{} { "EnforceTAP" } + htmlElement 'a' @{href = "https://www.fb-pro.com/enforce-suite/"; target = "_blank" } { + htmlElement 'img' @{ + src = $Settings.EnforceTAP + alt = "EnforceTAP" + style = "width: 125px; height: 200px;" + } {} + } + } + htmlElement 'div' @{ class = 'product-item' } { + htmlElement 'h3' @{} { " AuditTAP" } + htmlElement 'a' @{href = "https://www.fb-pro.com/audit-tap-product-information/"; target = "_blank" } { + htmlElement 'img' @{ + src = $Settings.ATAP + alt = "Audit Test Automation Package" + style = "width: 125px; height: 200px;" + } {} + } + } + } + + htmlElement 'div' @{class = 'contact-block' } { + htmlElement 'div' @{class = 'contact-flex' } { + #Flex-Container for FB Pro Contact information (order in one column, centered) + htmlElement 'div' @{ class = 'contact-item'; style = 'white-space: nowrap;' } { + + htmlElement 'h3' @{} { "Contact information" } + htmlElement 'p' @{} { "FB Pro GmbH" } + htmlElement 'p' @{} { htmlElement 'span' @{style = "display:inline-block; vertical-align:middle; position:relative; top:2px; margin-right:5px;" } { $phoneIcon }; "+49 6727 7559039" } + htmlElement 'p' @{} { + htmlElement 'span' @{style = "display:inline-block; vertical-align:middle; position:relative; top:2px; margin-right:5px;" } { $webIcon }; htmlElement 'a' @{href = "https://www.fb-pro.com/" ; target = "_blank" } { "https://www.fb-pro.com/" } + } + htmlElement 'p' @{} { + htmlElement 'span' @{style = "display:inline-block; vertical-align:middle; position:relative; top:2px; margin-right:5px;" } { $mailIcon }; htmlElement 'a' @{href = "mailto:info@fb-pro.com" } { "info@fb-pro.com" } + } + } + htmlElement 'div' @{class = 'contact-item' } { + htmlElement 'h3' @{} { "Can we help you?" } + htmlElement 'p' @{} { "Do you need support with system hardening?" } + htmlElement 'p' @{} { "Our team of system hardening experts will be happy to assist you." } + htmlElement 'p' @{} { " Contact us for a no-obligation inquiry!" } + } + } + + htmlElement 'div' @{ class = "contact-buttons" } { + htmlElement 'a' @{href = "mailto:info@fb-pro.com" } { + htmlElement 'button' @{id = "contactUsButton"; class = "button-base" } { "CONTACT US!" } + } + htmlElement 'a' @{href = "https://github.com/fbprogmbh/Hardening-Audit-Tool-AuditTAP-Audit-Test-Automation-Package"; target = "_blank" } { + htmlElement 'button' @{id = "githubButton"; class = "button-base" } { + "AuditTAP on GitHub" + } + } + } + } + } + } + } + + + + } + } + htmlElement 'script' @{ type = 'text/javascript' } { @" + function collapseHandler(e) { + var targetSection = e.target.parentElement.parentElement; + if (targetSection.classList.toggle('collapsed')) { + e.target.innerText = '+'; + } else { + e.target.innerText = '-'; + } + } + var collapseButtons = document.getElementsByClassName("collapseButton"); + for (var i = 0; i < collapseButtons.length; i++) { + collapseButtons[i].addEventListener('click', collapseHandler); + } +"@ + } + } + + $html = "$($head)$($body) " + + $head = " + + A Meaningful Page Title + + + " + + #If Path exists to a folder exists + if ($Path -match ".html") { + $name = Split-Path -Path $Path -Leaf + $Path = Split-Path -Path $Path -Parent + New-Item -Path $Path -Name $name -ItemType File -Value $html -Force + + } + else { + $Title = $Title -replace " Audit Report", "" + $auditReport += "$($Title)_$(Get-Date -UFormat %Y%m%d_%H%M%S).html" + New-Item -Path $Path -Name $auditReport -ItemType File -Value $html -Force + } + if ([System.Environment]::OSVersion.Platform -eq 'Unix') { + # $shellPath = $Path"/"$name + # bash -c "chmod o+r $($shellPath)" + # Write-Host $shellPath + } + #Create Report file + #$html | Out-File -FilePath $auditReport -Encoding utf8 + } +} diff --git a/ATAPHtmlReport/README.md b/ATAPHtmlReport/README.md new file mode 100644 index 0000000..c539401 --- /dev/null +++ b/ATAPHtmlReport/README.md @@ -0,0 +1,105 @@ +# ATAP Html Report + +## Overview + +A module part of the *Audit Test Automation Package* that creates html reports with tables and sections for audit reporting. + +## Requirements + +Please make sure, that following requirements are fulfilled: + +* **PowerShell 5.1:** To find out the current version use `$PSVersionTable.PSVersion`. + +## Installation + +It is recommended that you install the module on your system. + +1. Findout out where PowerShell stores modules with `$env:PSModulePath`. For example, this folder might be C:\Users\Administrator\Documents\WindowsPowerShell\Modules. +2. Copy this folder into the modules folder +3. Check with `Get-Module ATAPHtmlReport -ListAvailable` if PowerShell detects the module. + +## Usage + +To generate a report, use `Get-ATAPHtmlReport`. However, you will need to provide the *path* where the report will be stored, the report *title*, the audit *module name*, and what hardening standard it is *based on*. To give the report a little bit more context, about the computer the report was generated on, you can provide your own *host information* (a table at the beginning of the report). + +The main content of the report is structured into *sections*. A section must have a *title*, but can also include a *description*, a table of *AuditInfos*, and *SubSections*. AuditInfos represent a single audit test with an *Id*, *Task*, *Message*, and *Audit* that states whether the the system completed the test with True, False, Warning, or None. + +**Important**: To use the AuditInfos class defined in the modul, you need to add `using module ATAPHtmlReport` to the top of the file. This might not work if the module is not in a PSModulePath location. + +For example, a simple section could look like this: + +```powershell +[hashtable[]]$reportSections = @() + +$reportSections += @{ + Title = "Section 1" + Description = "All tests from section 1 of the my audit benchmark are here" + AuditInfos = @( + (New-Object -TypeName AuditInfo -Property @{ + Id = "1.1" + Task = "Ensure something is set" + Message = "All Good" + Audit = [AuditStatus]::True + }), + (New-Object -TypeName AuditInfo -Property @{ + Id = "1.2" + Task = "Ensure something else is set" + Message = "Result could be better" + Audit = [AuditStatus]::Warning + }) + ) +} +``` + +A more complicated section could look like this. + +```powershell +$reportSections += @{ + Title = "Section 2" + SubSections = @( + @{ + Title = "First subsection of section 2" + AuditInfos = @( + (New-Object -TypeName AuditInfo -Property @{ + Id = "2.1.1" + Task = "Ensure something" + Message = "Not entirely false" + Audit = [AuditStatus]::Warning + }), + (New-Object -TypeName AuditInfo -Property @{ + Id = "2.1.2" + Task = "Ensure something entirely different" + Message = "All good" + Audit = [AuditStatus]::True + }) + ) + }, + @{ + Title = "Second subsection of section 2" + AuditInfos = @( + (New-Object -TypeName AuditInfo -Property @{ + Id = "2.2.1" + Task = "Ensure something way different" + Message = "Oops, something went wrong!" + Audit = [AuditStatus]::False + }) + ) + } + ) +} +``` + +Tied up, the full usage of the `Get-ATAPHtmlReport` function could look like this: + +```powershell +Get-ATAPHtmlReport ` + -Path $Path ` + -Title "My Audit Benchmark" ` + -ModuleName "MyAuditBenchmark" ` + -BasedOn "My Audit Benchmarks Benchmark vX.X.X.X" ` + -HostInformation (Get-MyHostInformation) ` + -Sections $reportSections +``` + +## Troubleshooting +Using `Import-Module` instead of installing might not work. Please follow the outlined steps above. diff --git a/ATAPHtmlReport/Settings.psd1 b/ATAPHtmlReport/Settings.psd1 new file mode 100644 index 0000000..58108ab --- /dev/null +++ b/ATAPHtmlReport/Settings.psd1 @@ -0,0 +1,57 @@ +<# +BSD 3-Clause License + +Copyright (c) 2023, FB Pro GmbH +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#> + +<# + Author(s): Benedikt Böhme, Dennis Esly + Date: 07/20/2018 + Version: 1.0 + Last Change: 07/20/2018 +#> + +@{ + PackageLink = "https://github.com/fbprogmbh/Audit-Test-Automation" + SolutionsLink = "https://www.fb-pro.com/enforce-suite" + + Logo = "data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABkAAD/4QNvaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6QTcyNUZDMjEzNUVERTYxMUI1OUFCMjU2NDI2OUE3NUMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6Q0I2NjA2RUZFRDM1MTFFNjgzQTBBNkY4RDhEOEM1RjMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Q0I2NjA2RUVFRDM1MTFFNjgzQTBBNkY4RDhEOEM1RjMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBNzI1RkMyMTM1RURFNjExQjU5QUIyNTY0MjY5QTc1QyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBNzI1RkMyMTM1RURFNjExQjU5QUIyNTY0MjY5QTc1QyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6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" + + LogoSvg = "" + + EA = "data:image/jpeg;base64,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" + + ATAP = " data:image/jpeg;base64,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" + + EnforceTap = "data:image/png;base64,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jFJKfMrE1/FqtQpF5d+g4ICvVb35ha+cyEUWyqIIQhRyAfCPWQoFhD4mBRF08AZRBxI5MkBgKZWrbeVqJYhKCDxxuaJKESlVz5LZ8xe89tbbzzz/wl+eePyXv779+htuuvq66yEvufyyM88977d33a0zjYEAHxCN4PF/BZjuZldb9aZxgNLq06oPcCuShUOrLOwrLlEWaPq36jA65yCbQDII/I4DC6gAQhTRCMcRKEiCK2AMeIO9qQAohVgFZ9QM2oFqqAESvEFQIXw3ZAEpFLaoKIxL5UqNhFzY2f3q62889pfH7/7d72/95dTrbrjxlImTxk+YdPK4CSedMv7EceNPGj/hlAkTx02cdM111113802/uO22X915529/97v7//CHl19/w5EoIhF+oatLATMPsDIPtAxw+LcnmT9cD5k/2J95KT7MSzEuf/hgBtD0aepQgMIOpQCSBQkKQoAuURTBAupwfkEBRWCHhDOIBR0ofJDs6uqaNWvW2+++84+XX332mece/MNDv5p6+8+u+vn551340zPPOO3Un+62+/d/sMcP99r7Rwce8OMjjz5q3CkTzjrn7Isvvfye++6754EHH/zjw4898eTzL704bcb0Bd3d9Syb17lQG/+nINjyVBDV2joQwBC90DqwTBohD8j73C+Q/AQCnftQvfqw/qi8KNIqYfyn0SRKUQMIsVQg6gDYnuAGrgBQsI6lUgk96e7unjFjxquvvvrcc8/95S9/+dOf/nT77bffdtttN95445VXXnnBBRf89Kc/nTRp0vjx43/yk5+MPeGECZMnn3XuuZddeeV1N95469Spv7rjjlffeOPtadNmzZmzECxJU8scxHGlWpNBIFUAqcIQEtFLBGE/wkhIZIUchCBTV1+9q6eviKJCOIsjuWFrBBSrrP8P6uJYTyQEDnLO/60ABoAX4d6Hba57wV74n+LVFJKL4cgbnWXK/ftL5XpuwWtQlITPkoD9QwE1CMITRX8hTLFj/wBRSCOoFegQ7CTYoYR3gzt63V+2+aupcD6QordNIyoBnC+eNyTwFEzOS+u8EwRARb50TjqrcgQmC7WJjI61jrIMKKVZZG1kAB1pb491GmceNW3bGg1euHD+rOmvvvry408/ed9DD/zm/9110aWXnX3+uVNOPf2UieNPGTdh3KQJkyafOum0KRddfOlFl11yxZU/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" + +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/Compare-EqualCISVersions.Tests.ps1 b/ATAPHtmlReport/Tests/Compare-EqualCISVersions.Tests.ps1 new file mode 100644 index 0000000..eb0d0d6 --- /dev/null +++ b/ATAPHtmlReport/Tests/Compare-EqualCISVersions.Tests.ps1 @@ -0,0 +1,224 @@ + +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + + +InModuleScope ATAPHtmlReport { + Describe 'Testing Compare-EqualCISVersions' { + + It 'Test Windows 7' { + $BasedOn = @( + "CIS Microsoft Windows 7 Workstation Benchmark, Version: 3.1.0, Date: 2018-03-02" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.1.0, Date: 2021-04-15" + ) + $MitreMappingCompatible = @("CIS Microsoft Windows 10 Stand-alone Benchmark, Version: 1.0.1, Date: 2022-02-08", + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 1.0.0, Date: 2022-11-15", + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15", + "CIS Microsoft Windows 11 Enterprise Release 21H2 Benchmark, Version: 21H2, Date: 2022-02-14", + "CIS Microsoft Windows Server 2019 Benchmark, Version: 1.3.0, Date: 2022-03-18", + "CIS Microsoft Windows Server 2022, Version: 1.0.0, Date 2022-02-14") + try { + Compare-EqualCISVersions -Title "Windows Server 2019 Audit Report" -ReportBasedOn:$BasedOn -MitreMappingCompatible:$MitreMappingCompatible | Should -Be $false + } + + catch { + $false | Should -Be $true + } + } + It 'Test Windows 10' { + $BasedOn = @( + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15" + "DISA Windows 10 Security Technical Implementation Guide, Version: V1R16, Date: 2019-10-25" + "Microsoft Security baseline (FINAL) for Windows 10, Version: 21H1, Date: 2021-05-18" + "Configuration Recommendations for Hardening of Windows 10 Using Built-in Functionalities: Version 1.3, Date: 2021-05-03" + "SiSyPHuS Recommendations for Telemetry Components: Version 1.2, Date: 2020-04-27" + "ACSC Hardening Microsoft Windows 10 version 21H1 Workstations, Version: 10.2021, Date 2021-10-01" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.1.0, Date: 2021-04-15" + "FB Pro recommendations 'Enhanced settings', Version 1.1.0, Date: 2023-02-24" + ) + $MitreMappingCompatible = @("CIS Microsoft Windows 10 Stand-alone Benchmark, Version: 1.0.1, Date: 2022-02-08", + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 1.0.0, Date: 2022-11-15", + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15", + "CIS Microsoft Windows 11 Enterprise Release 21H2 Benchmark, Version: 21H2, Date: 2022-02-14", + "CIS Microsoft Windows Server 2019 Benchmark, Version: 1.3.0, Date: 2022-03-18", + "CIS Microsoft Windows Server 2022, Version: 1.0.0, Date 2022-02-14") + try { + Compare-EqualCISVersions -Title "Windows Server 2019 Audit Report" -ReportBasedOn:$BasedOn -MitreMappingCompatible:$MitreMappingCompatible | Should -Be $true + } + + catch { + $false | Should -Be $true + } + } + It 'Test Windows 10 stand-alone' { + $BasedOn = @( + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 1.0.0, Date: 2022-11-15" + "Configuration Recommendations for Hardening of Windows 10 Using Built-in Functionalities: Version 1.3, Date: 2021-05-03" + "SiSyPHuS Recommendations for Telemetry Components: Version 1.1, Date: 2019-07-31" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.1.0, Date: 2021-04-15" + "FB Pro recommendations 'Enhanced settings', Version 1.1.0, Date: 2023-02-24" + ) + $MitreMappingCompatible = @("CIS Microsoft Windows 10 Stand-alone Benchmark, Version: 1.0.1, Date: 2022-02-08", + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 1.0.0, Date: 2022-11-15", + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15", + "CIS Microsoft Windows 11 Enterprise Release 21H2 Benchmark, Version: 21H2, Date: 2022-02-14", + "CIS Microsoft Windows Server 2019 Benchmark, Version: 1.3.0, Date: 2022-03-18", + "CIS Microsoft Windows Server 2022, Version: 1.0.0, Date 2022-02-14") + try { + Compare-EqualCISVersions -Title "Windows Server 2019 Audit Report" -ReportBasedOn:$BasedOn -MitreMappingCompatible:$MitreMappingCompatible | Should -Be $true + } + + catch { + $false | Should -Be $true + } + } + It 'Test Windows 11' { + $BasedOn = @( + "CIS Microsoft Windows 11 Enterprise Release 21H2 Benchmark, Version: 21H2, Date: 2022-02-14" + "Security baseline for Microsoft Windows 11, Version: 20H2, Date: 2020-12-17" + "Configuration Recommendations for Hardening of Windows 10 Using Built-in Functionalities: Version 1.3, Date: 2021-05-03" + "SiSyPHuS Recommendations for Telemetry Components: Version 1.1, Date: 2019-07-31" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.1.0, Date: 2021-04-15" + "FB Pro recommendations 'Enhanced settings', Version 1.1.0, Date: 2023-02-24" + ) + $MitreMappingCompatible = @("CIS Microsoft Windows 10 Stand-alone Benchmark, Version: 1.0.1, Date: 2022-02-08", + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 1.0.0, Date: 2022-11-15", + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15", + "CIS Microsoft Windows 11 Enterprise Release 21H2 Benchmark, Version: 21H2, Date: 2022-02-14", + "CIS Microsoft Windows Server 2019 Benchmark, Version: 1.3.0, Date: 2022-03-18", + "CIS Microsoft Windows Server 2022, Version: 1.0.0, Date 2022-02-14") + try { + Compare-EqualCISVersions -Title "Windows Server 2019 Audit Report" -ReportBasedOn:$BasedOn -MitreMappingCompatible:$MitreMappingCompatible | Should -Be $true + } + + catch { + $false | Should -Be $true + } + } + It 'Test Windows 11 stand-alone' { + $BasedOn = @( + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 1.0.0, Date: 2022-11-15" + "Configuration Recommendations for Hardening of Windows 10 Using Built-in Functionalities: Version 1.3, Date: 2021-05-03" + "SiSyPHuS Recommendations for Telemetry Components: Version 1.1, Date: 2019-07-31" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.1.0, Date: 2021-04-15" + "FB Pro recommendations 'Enhanced settings', Version 1.1.0, Date: 2023-02-24" + ) + $MitreMappingCompatible = @("CIS Microsoft Windows 10 Stand-alone Benchmark, Version: 1.0.1, Date: 2022-02-08", + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 1.0.0, Date: 2022-11-15", + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15", + "CIS Microsoft Windows 11 Enterprise Release 21H2 Benchmark, Version: 21H2, Date: 2022-02-14", + "CIS Microsoft Windows Server 2019 Benchmark, Version: 1.3.0, Date: 2022-03-18", + "CIS Microsoft Windows Server 2022, Version: 1.0.0, Date 2022-02-14") + try { + Compare-EqualCISVersions -Title "Windows Server 2019 Audit Report" -ReportBasedOn:$BasedOn -MitreMappingCompatible:$MitreMappingCompatible | Should -Be $true + } + + catch { + $false | Should -Be $true + } + } + It 'Test Windows Server 2019' { + $BasedOn = @( + "Windows Server 2019 Security Technical Implementation Guide, Version: 1.5, Date: 2020-06-17" + "CIS Microsoft Windows Server 2019 Benchmark, Version: 1.3.0, Date: 2022-03-18" + "Microsoft Security baseline for Windows Server 2019, Version: FINAL, Date 2019-06-18" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.1.0, Date: 2021-04-15" + "FB Pro recommendations 'Enhanced settings', Version 1.1.0, Date: 2023-02-24" + ) + $MitreMappingCompatible = @("CIS Microsoft Windows 10 Stand-alone Benchmark, Version: 1.0.1, Date: 2022-02-08", + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 1.0.0, Date: 2022-11-15", + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15", + "CIS Microsoft Windows 11 Enterprise Release 21H2 Benchmark, Version: 21H2, Date: 2022-02-14", + "CIS Microsoft Windows Server 2019 Benchmark, Version: 1.3.0, Date: 2022-03-18", + "CIS Microsoft Windows Server 2022, Version: 1.0.0, Date 2022-02-14") + try { + Compare-EqualCISVersions -Title "Windows Server 2019 Audit Report" -ReportBasedOn:$BasedOn -MitreMappingCompatible:$MitreMappingCompatible | Should -Be $true + } + + catch { + $false | Should -Be $true + } + } + It 'Test Windows Server 2022' { + $BasedOn = @( + "Security baseline for Microsoft Windows Server 2022, Version: FINAL, Date 2021-09-27" + "CIS Microsoft Windows Server 2022, Version: 1.0.0, Date 2022-02-14" + "DISA Windows Server 2022, Version: V1R1, Date 2022-09-28" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.1.0, Date: 2021-04-15" + "FB Pro recommendations 'Enhanced settings', Version 1.1.0, Date: 2023-02-24" + ) + $MitreMappingCompatible = @("CIS Microsoft Windows 10 Stand-alone Benchmark, Version: 1.0.1, Date: 2022-02-08" + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 1.0.0, Date: 2022-11-15" + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15" + "CIS Microsoft Windows 11 Enterprise Release 21H2 Benchmark, Version: 21H2, Date: 2022-02-14" + "CIS Microsoft Windows Server 2019 Benchmark, Version: 1.3.0, Date: 2022-03-18" + "CIS Microsoft Windows Server 2022, Version: 1.0.0, Date 2022-02-14") + try { + Compare-EqualCISVersions -Title "Windows Server 2022 Audit Report" -ReportBasedOn:$BasedOn -MitreMappingCompatible:$MitreMappingCompatible | Should -Be $true + } + + catch { + $false | Should -Be $true + } + } + It 'Test for unmatching versions of CIS and MITRE mapping' { + $BasedOn = @( + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.15.0, Date: 2023-02-15" + "DISA Windows 10 Security Technical Implementation Guide, Version: V1R16, Date: 2019-10-25" + "Microsoft Security baseline (FINAL) for Windows 10, Version: 21H1, Date: 2021-05-18" + "Configuration Recommendations for Hardening of Windows 10 Using Built-in Functionalities: Version 1.3, Date: 2021-05-03" + "SiSyPHuS Recommendations for Telemetry Components: Version 1.2, Date: 2020-04-27" + "ACSC Hardening Microsoft Windows 10 version 21H1 Workstations, Version: 10.2021, Date 2021-10-01" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.1.0, Date: 2021-04-15" + "FB Pro recommendations 'Enhanced settings', Version 1.1.0, Date: 2023-02-24" + ) + $MitreMappingCompatible = @("CIS Microsoft Windows 10 Stand-alone Benchmark, Version: 1.0.1, Date: 2022-02-08", + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 1.0.0, Date: 2022-11-15", + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15", + "CIS Microsoft Windows 11 Enterprise Release 21H2 Benchmark, Version: 21H2, Date: 2022-02-14", + "CIS Microsoft Windows Server 2019 Benchmark, Version: 1.3.0, Date: 2022-03-18", + "CIS Microsoft Windows Server 2022, Version: 1.0.0, Date 2022-02-14") + Compare-EqualCISVersions -Title "Windows 10 Report" -ReportBasedOn:$BasedOn -MitreMappingCompatible:$MitreMappingCompatible | Should -Be $false + } + + It 'Test for matching versions of CIS and MITRE mapping' { + $BasedOn = @( + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15" + "DISA Windows 10 Security Technical Implementation Guide, Version: V1R16, Date: 2019-10-25" + "Microsoft Security baseline (FINAL) for Windows 10, Version: 21H1, Date: 2021-05-18" + "Configuration Recommendations for Hardening of Windows 10 Using Built-in Functionalities: Version 1.3, Date: 2021-05-03" + "SiSyPHuS Recommendations for Telemetry Components: Version 1.2, Date: 2020-04-27" + "ACSC Hardening Microsoft Windows 10 version 21H1 Workstations, Version: 10.2021, Date 2021-10-01" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.1.0, Date: 2021-04-15" + "FB Pro recommendations 'Enhanced settings', Version 1.1.0, Date: 2023-02-24" + ) + $MitreMappingCompatible = @("CIS Microsoft Windows 10 Stand-alone Benchmark, Version: 1.0.1, Date: 2022-02-08", + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 1.0.0, Date: 2022-11-15", + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15", + "CIS Microsoft Windows 11 Enterprise Release 21H2 Benchmark, Version: 21H2, Date: 2022-02-14", + "CIS Microsoft Windows Server 2019 Benchmark, Version: 1.3.0, Date: 2022-03-18", + "CIS Microsoft Windows Server 2022, Version: 1.0.0, Date 2022-02-14") + Compare-EqualCISVersions -Title "Windows 10 Report" -ReportBasedOn:$BasedOn -MitreMappingCompatible:$MitreMappingCompatible | Should -Be $true + } + + It 'Test for matching versions of CIS and MITRE mapping but wrong OS' { + $BasedOn = @( + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15" + "DISA Windows 10 Security Technical Implementation Guide, Version: V1R16, Date: 2019-10-25" + "Microsoft Security baseline (FINAL) for Windows 10, Version: 21H1, Date: 2021-05-18" + "Configuration Recommendations for Hardening of Windows 10 Using Built-in Functionalities: Version 1.3, Date: 2021-05-03" + "SiSyPHuS Recommendations for Telemetry Components: Version 1.2, Date: 2020-04-27" + "ACSC Hardening Microsoft Windows 10 version 21H1 Workstations, Version: 10.2021, Date 2021-10-01" + "FB Pro recommendations 'Ciphers Protocols and Hashes Benchmark', Version 1.1.0, Date: 2021-04-15" + "FB Pro recommendations 'Enhanced settings', Version 1.1.0, Date: 2023-02-24" + ) + $MitreMappingCompatible = @("CIS Microsoft Windows 10 Stand-alone Benchmark, Version: 1.0.1, Date: 2022-02-08", + "CIS Microsoft Windows 11 Stand-alone Benchmark, Version: 1.0.0, Date: 2022-11-15", + "CIS Microsoft Windows 10 Enterprise Release 21H1 Benchmark, Version: 1.12.0, Date: 2022-02-15", + "CIS Microsoft Windows 11 Enterprise Release 21H2 Benchmark, Version: 21H2, Date: 2022-02-14", + "CIS Microsoft Windows Server 2019 Benchmark, Version: 1.3.0, Date: 2022-03-18", + "CIS Microsoft Windows Server 2022, Version: 1.0.0, Date 2022-02-14") + Compare-EqualCISVersions -Title "Debian 10" -ReportBasedOn:$BasedOn -MitreMappingCompatible:$MitreMappingCompatible | Should -Be $false + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/ConvertTo-HtmlTable.Tests.ps1 b/ATAPHtmlReport/Tests/ConvertTo-HtmlTable.Tests.ps1 new file mode 100644 index 0000000..7cc9a7a --- /dev/null +++ b/ATAPHtmlReport/Tests/ConvertTo-HtmlTable.Tests.ps1 @@ -0,0 +1,50 @@ + +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + +InModuleScope ATAPHtmlReport { + Describe 'Testing ConvertTo-HtmlTable' { + It 'tests with an example Report' { + + $AuditInfos = @{Id = "1.1.4" + Status = [AuditInfoStatus]::False + }, + @{Id = "1.2.3" + Status = [AuditInfoStatus]::True + }, + @{Id = "1.2.4" + Status = [AuditInfoStatus]::True + }, + @{Id = "1.2.6" + Status = [AuditInfoStatus]::True + }, + @{Id = "1.2.5" + Status = [AuditInfoStatus]::False + }, + @{Id = "1.4.5" + Status = [AuditInfoStatus]::True + } + + $Subsection = @{AuditInfos = $AuditInfos } + + $Section1 = @{Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $Section2 = @{Title = "DISA" + $Subsection = $null + } + + $Sections = $Section1, $Section2 + + + $Mappings = $Sections | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + # call the function under test and split by opening and closing brackets. Result should be an array of tags. + $tags = (ConvertTo-HtmlTable $Mappings.map).Split("<").Split(">") + $tags | Should -Contain 'table id="MITRETable"' + $tags | Should -Contain 'a href="https://attack.mitre.org/tactics/TA0007/"' + $tags | Should -Contain 'Discovery' + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/Get-ColorValue.Tests.ps1 b/ATAPHtmlReport/Tests/Get-ColorValue.Tests.ps1 new file mode 100644 index 0000000..96577f9 --- /dev/null +++ b/ATAPHtmlReport/Tests/Get-ColorValue.Tests.ps1 @@ -0,0 +1,55 @@ +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + +InModuleScope ATAPHtmlReport { + Describe "Testing Get-ColorValue" { + It "Should return hundred" { + $result = Get-ColorValue -FirstValue 10 -SecondValue 10 + $result | Should -Be "#33cca6" + } + It "Should return ninety" { + $result = Get-ColorValue -FirstValue 9 -SecondValue 10 + $result | Should -Be "#52CC8F" + } + It "Should return eighty" { + $result = Get-ColorValue -FirstValue 8 -SecondValue 10 + $result | Should -Be "#70CC78" + } + It "Should return seventy" { + $result = Get-ColorValue -FirstValue 7 -SecondValue 10 + $result | Should -Be "#8FCC61" + } + It "Should return sixty" { + $result = Get-ColorValue -FirstValue 6 -SecondValue 10 + $result | Should -Be "#ADCC4A" + } + It "Should return fifty" { + $result = Get-ColorValue -FirstValue 5 -SecondValue 10 + $result | Should -Be "#CCCC33" + } + It "Should return fourty" { + $result = Get-ColorValue -FirstValue 4 -SecondValue 10 + $result | Should -Be "#CCA329" + } + It "Should return thirty" { + $result = Get-ColorValue -FirstValue 3 -SecondValue 10 + $result | Should -Be "#CC7A1F" + } + It "Should return twenty" { + $result = Get-ColorValue -FirstValue 2 -SecondValue 10 + $result | Should -Be "#CC5214" + } + It "Should return ten" { + $result = Get-ColorValue -FirstValue 1 -SecondValue 10 + $result | Should -Be "#CC290A" + } + It "Should return zero" { + $result = Get-ColorValue -FirstValue 0 -SecondValue 10 + $result | Should -Be "#cc0000" + } + It "Should return empty" { + $result = Get-ColorValue -FirstValue 0 -SecondValue 0 + $result | Should -Be "#a7a7a7" + } + } +} diff --git a/ATAPHtmlReport/Tests/Get-MitigationsFromFailedTests.Tests.ps1 b/ATAPHtmlReport/Tests/Get-MitigationsFromFailedTests.Tests.ps1 new file mode 100644 index 0000000..e929ce1 --- /dev/null +++ b/ATAPHtmlReport/Tests/Get-MitigationsFromFailedTests.Tests.ps1 @@ -0,0 +1,419 @@ +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" +$global:CISToAttackMappingData = Get-Content -Raw "$PSScriptRoot\..\resources\CISToAttackMappingData.json" | ConvertFrom-Json + +InModuleScope ATAPHtmlReport { + function global:Add-ToAuditInfos{ + param( + [Parameter(Mandatory = $true)] + [string] + $Mitigation, + [Parameter(Mandatory = $true)] + [bool] + $AllIDsFalse + ) + $json = $CISToAttackMappingData.'CISAttackMapping' + $json.psobject.properties.name | Where-Object {$json.$_.'Mitigation1' -eq $Mitigation -or $json.$_.'Mitigation2' -eq $Mitigation} | ForEach-Object {return $json.$_.'Recommendation'} | ForEach-Object { + if($AllIDsFalse) { + $global:AuditInfos += @{ + Id = $_ + Status = [AuditInfoStatus]::False + } + } + else { + $global:AuditInfos += @{ + Id = $_ + Status = [AuditInfoStatus]::True + } + } + } + } + Describe 'testing function Get-MitigationsFromFailedTests' { + It 'tests the amount of techniques in report' { + $global:AuditInfos = @() + + $global:AuditInfos += @{ + #T1489 + Id = "18.8.5.3" + Status = [AuditInfoStatus]::False + } + $global:AuditInfos += @{ + #T1555 + Id = "18.9.65.2.2" + Status = [AuditInfoStatus]::False + } + $global:AuditInfos += @{ + #T1569 #T1011 + Id = "5.1" + Status = [AuditInfoStatus]::False + } + $global:AuditInfos += @{ + #T1115 + Id = "2.2.1" + Status = [AuditInfoStatus]::False + } + $global:AuditInfos += @{ + #T1048 + Id = "5.12" + Status = [AuditInfoStatus]::False + } + $global:AuditInfos += @{ + #T1059 + Id = "18.9.31.4" + Status = [AuditInfoStatus]::False + } + $global:AuditInfos += @{ + #T1003 + Id = "1.1.7" + Status = [AuditInfoStatus]::False + } + $global:AuditInfos += @{ + #T1016 + Id = "18.5.19.2.1" + Status = [AuditInfoStatus]::False + } + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + + $json = $CISToAttackMappingData.'CISAttackMapping' + + foreach($Mitigation in $CISAMitigations.Keys) { + $Techniques = @() + $global:AuditInfos | Where-Object {$_.Status -eq [AuditInfoStatus]::False} | + Where-Object {$json.($_.Id).'Mitigation1' -eq $Mitigation -or $json.($_.Id).'Mitigation2' -eq $Mitigation} | + ForEach-Object { + if($null -ne $json.($_.Id).'Technique1' -and $Techniques -notcontains $json.($_.Id).'Technique1'){ + $Techniques += $json.($_.Id).'Technique1' + } + if($null -ne $json.($_.Id).'Technique2' -and $Techniques -notcontains $json.($_.Id).'Technique2'){ + $Techniques += $json.($_.Id).'Technique2' + } + } + $Techniques = $Techniques | Sort-Object + $CISAMitigations[$Mitigation]['MitreTechniqueIDs'] = $CISAMitigations[$Mitigation]['MitreTechniqueIDs'] | Sort-Object + for($i = 0; $i -lt $CISAMitigations[$Mitigation]['MitreTechniqueIDs'].length; $i++) { + $CISAMitigations[$Mitigation]['MitreTechniqueIDs'][$i] | Should -Be $Techniques[$i] + } + } + } + It 'tests with an example report where every status is [AuditInfoStatus]::False' { + $global:AuditInfos = @() + + Add-ToAuditInfos -Mitigation 'M1017' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1018' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1021' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1027' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1028' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1030' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1031' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1038' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1041' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1042' -AllIDsFalse $true + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + #Tests + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + $CISAMitigations.Keys | Should -Be @('M1017', 'M1018', 'M1021', 'M1027', 'M1028', 'M1030', 'M1031', 'M1038', 'M1041', 'M1042') + } + It 'tests with an example report where every status is [AuditInfoStatus]::True' { + $global:AuditInfos = @() + + Add-ToAuditInfos -Mitigation 'M1017' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1018' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1021' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1027' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1028' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1030' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1031' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1038' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1041' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1042' -AllIDsFalse $false + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + #Tests + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + $CISAMitigations.Keys | Should -Be @() + } + It 'tests with an example report where just M1017 ids are [AuditInfoStatus]::False' { + $global:AuditInfos = @() + + Add-ToAuditInfos -Mitigation 'M1017' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1018' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1021' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1027' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1028' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1030' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1031' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1038' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1041' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1042' -AllIDsFalse $false + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + #Tests + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + $CISAMitigations.Keys | Should -Contain @('M1017') + } + It 'tests with an example report where just M1018 ids are [AuditInfoStatus]::False' { + $global:AuditInfos = @() + + Add-ToAuditInfos -Mitigation 'M1017' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1018' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1021' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1027' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1028' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1030' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1031' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1038' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1041' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1042' -AllIDsFalse $false + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + #Tests + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + $CISAMitigations.Keys | Should -Contain @('M1018') + } + It 'tests with an example report where just M1021 ids are [AuditInfoStatus]::False' { + $global:AuditInfos = @() + + Add-ToAuditInfos -Mitigation 'M1017' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1018' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1021' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1027' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1028' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1030' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1031' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1038' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1041' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1042' -AllIDsFalse $false + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + #Tests + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + $CISAMitigations.Keys | Should -Contain @('M1021') + } + It 'tests with an example report where just M1027 ids are [AuditInfoStatus]::False' { + $global:AuditInfos = @() + + Add-ToAuditInfos -Mitigation 'M1017' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1018' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1021' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1027' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1028' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1030' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1031' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1038' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1041' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1042' -AllIDsFalse $false + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + #Tests + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + $CISAMitigations.Keys | Should -Contain @('M1027') + } + It 'tests with an example report where just M1028 ids are [AuditInfoStatus]::False' { + $global:AuditInfos = @() + + Add-ToAuditInfos -Mitigation 'M1017' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1018' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1021' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1027' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1028' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1030' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1031' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1038' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1041' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1042' -AllIDsFalse $false + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + #Tests + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + $CISAMitigations.Keys | Should -Contain @('M1028') + } + It 'tests with an example report where just M1030 ids are [AuditInfoStatus]::False' { + $global:AuditInfos = @() + + Add-ToAuditInfos -Mitigation 'M1017' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1018' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1021' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1027' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1028' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1030' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1031' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1038' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1041' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1042' -AllIDsFalse $false + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + #Tests + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + $CISAMitigations.Keys | Should -Contain @('M1030') + } + It 'tests with an example report where just M1031 ids are [AuditInfoStatus]::False' { + $global:AuditInfos = @() + + Add-ToAuditInfos -Mitigation 'M1017' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1018' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1021' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1027' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1028' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1030' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1031' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1038' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1041' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1042' -AllIDsFalse $false + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + #Tests + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + $CISAMitigations.Keys | Should -Contain @('M1031') + } + It 'tests with an example report where just M1038 ids are [AuditInfoStatus]::False' { + $global:AuditInfos = @() + + Add-ToAuditInfos -Mitigation 'M1017' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1018' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1021' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1027' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1028' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1030' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1031' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1038' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1041' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1042' -AllIDsFalse $false + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + #Tests + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + $CISAMitigations.Keys | Should -Contain @('M1038') + } + It 'tests with an example report where just M1041 ids are [AuditInfoStatus]::False' { + $global:AuditInfos = @() + + Add-ToAuditInfos -Mitigation 'M1017' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1018' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1021' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1027' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1028' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1030' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1031' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1038' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1041' -AllIDsFalse $true + Add-ToAuditInfos -Mitigation 'M1042' -AllIDsFalse $false + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + #Tests + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + $CISAMitigations.Keys | Should -Contain @('M1041') + } + It 'tests with an example report where just M1042 ids are [AuditInfoStatus]::False' { + $global:AuditInfos = @() + + Add-ToAuditInfos -Mitigation 'M1017' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1018' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1021' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1027' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1028' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1030' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1031' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1038' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1041' -AllIDsFalse $false + Add-ToAuditInfos -Mitigation 'M1042' -AllIDsFalse $true + + $Subsection = @{AuditInfos = $global:AuditInfos } + $Section1 = @{ + Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + #Tests + $CISAMitigations = $mitreMap.Map | Get-MitigationsFromFailedTests + $CISAMitigations.Keys | Should -Contain @('M1042') + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/Get-MitreTacticName.Tests.ps1 b/ATAPHtmlReport/Tests/Get-MitreTacticName.Tests.ps1 new file mode 100644 index 0000000..e16354f --- /dev/null +++ b/ATAPHtmlReport/Tests/Get-MitreTacticName.Tests.ps1 @@ -0,0 +1,12 @@ +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + +InModuleScope ATAPHtmlReport { + Describe 'Testing Get-MitreTacticName' { + It 'tests with example Values' { + Get-MitreTacticName -TacticId 'TA0042' | Should -Be "Resource Development" + Get-MitreTacticName -TacticId 'TA0004' | Should -Be "Privilege Escalation" + Get-MitreTacticName -TacticId 'TA0008' | Should -Be "Lateral Movement" + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/Get-MitreTactics.Tests.ps1 b/ATAPHtmlReport/Tests/Get-MitreTactics.Tests.ps1 new file mode 100644 index 0000000..b8c1fd2 --- /dev/null +++ b/ATAPHtmlReport/Tests/Get-MitreTactics.Tests.ps1 @@ -0,0 +1,13 @@ +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + +InModuleScope ATAPHtmlReport { + Describe 'Testing Get-MitreTactics' { + It 'tests with example Values' { + + Get-MitreTactics -TechniqueID "T1591" | Should -Be 'TA0043' + + Get-MitreTactics -TechniqueID "T1056" | Should -Be 'TA0009', 'TA0006' + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/Get-MitreTechniqueName.Tests.ps1 b/ATAPHtmlReport/Tests/Get-MitreTechniqueName.Tests.ps1 new file mode 100644 index 0000000..404c543 --- /dev/null +++ b/ATAPHtmlReport/Tests/Get-MitreTechniqueName.Tests.ps1 @@ -0,0 +1,17 @@ +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + +InModuleScope ATAPHtmlReport { + Describe 'Testing Get-MitreTechniqueName' { + It 'tests with example values' { + Get-MitreTechniqueName -TechniqueID "T1591" | Should -Be 'Gather Victim Org Information' + Get-MitreTechniqueName -TechniqueID "T1056" | Should -Be 'Input Capture' + Get-MitreTechniqueName -TechniqueID "T1056" | Should -BeOfType String + } + + It 'tests with wrong values' { + Get-MitreTechniqueName -TechniqueID "TXXXX" | Should -Be $null + Get-MitreTechniqueName -TechniqueID "TXXXX" | Should -Not -Be 'Input Capture' + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/Get-TacticCounter.Tests.ps1 b/ATAPHtmlReport/Tests/Get-TacticCounter.Tests.ps1 new file mode 100644 index 0000000..f8bc8f1 --- /dev/null +++ b/ATAPHtmlReport/Tests/Get-TacticCounter.Tests.ps1 @@ -0,0 +1,71 @@ +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + +InModuleScope ATAPHtmlReport { + + Describe "Testing Get-TacticCounter" { + Context "When counting for a tactic without mapped tests" { + It "Should return 0" { + $AuditInfos = @{Id = "1.1.4" + Status = [AuditInfoStatus]::False + }, + @{Id = "1.2.3" + Status = [AuditInfoStatus]::True + }, + @{Id = "1.2.4" + Status = [AuditInfoStatus]::True + }, + @{Id = "1.2.6" + Status = [AuditInfoStatus]::True + }, + @{Id = "1.2.5" + Status = [AuditInfoStatus]::False + }, + @{Id = "1.4.5" + Status = [AuditInfoStatus]::True + } + + $Subsection = @{AuditInfos = $AuditInfos } + + $Section1 = @{Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $Sections = $Section1 + + + $Mappings = $Sections | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + $result = Get-TacticCounter -tactic $Mappings.Map["TA0042"] $Mappings.Map + $result | Should -Be 0 + } + } + + Context "Counter should be 1 if a technique is a 100% fullfilled" { + It "Should be 1" { + $AuditInfos = @{Id = "18.9.48.13" + Status = [AuditInfoStatus]::True + }, + @{Id = "18.9.87.1" + Status = [AuditInfoStatus]::True + } + + $Subsection = @{AuditInfos = $AuditInfos } + + $Section1 = @{Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $Sections = $Section1 + + + $Mappings = $Sections | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + + $Mappings.Map["TA0043"]["T1592"]["18.9.87.1"] | Should -Be True + $Mappings.Map["TA0043"]["T1592"]["18.9.48.13"] | Should -Be True + $Mappings.Map["TA0043"]["T1592"].count | Should -Be 2 + Get-TacticCounter "TA0043" $Mappings.Map | Should -Be 1 + } + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/Merge-CisAuditsToMitreMap.Tests.ps1 b/ATAPHtmlReport/Tests/Merge-CisAuditsToMitreMap.Tests.ps1 new file mode 100644 index 0000000..fdffa85 --- /dev/null +++ b/ATAPHtmlReport/Tests/Merge-CisAuditsToMitreMap.Tests.ps1 @@ -0,0 +1,50 @@ + +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + +InModuleScope ATAPHtmlReport { + Describe 'Testing Merge-CisAuditsToMitreMap' { + It 'tests with an example Report' { + + $AuditInfos = @{Id = "1.1.4" + Status = [AuditInfoStatus]::False + }, + @{Id = "1.2.3" + Status = [AuditInfoStatus]::True + }, + @{Id = "1.2.5" + Status = [AuditInfoStatus]::False + }, + @{Id = "1.4.5" + Status = [AuditInfoStatus]::True + } + + $Subsection = @{AuditInfos = $AuditInfos } + + $Section1 = @{Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $Section2 = @{Title = "DISA" + $Subsection = $null + } + + $Sections = $Section1, $Section2 + + $mapping = $Sections | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + foreach ($tactic in $mapping.Keys) { + Write-Host "$tactic = " + foreach ($technique in $($mapping[$tactic]).Keys) { + Write-Host " $technique = " + foreach ($id in $($($mapping[$tactic])[$technique]).Keys) { + Write-Host " $id = $($($($mapping[$tactic])[$technique])[$id])" + } + } + } + + $mapping.GetType() | Should -Be "MitreMap" + $mapping.Map["TA0001"]["T1078"]["1.1.4"] | Should -Be False + $mapping.Map["TA0006"]["T1110"]["1.2.3"] | Should -Be True + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/MitreMap.Tests.ps1 b/ATAPHtmlReport/Tests/MitreMap.Tests.ps1 new file mode 100644 index 0000000..38216b6 --- /dev/null +++ b/ATAPHtmlReport/Tests/MitreMap.Tests.ps1 @@ -0,0 +1,101 @@ + +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + + +InModuleScope ATAPHtmlReport { + Describe 'Testing MitreMap' { + It 'tests correct amount of techniques per tacitc' { + $mitreMap = [MitreMap]::new() + #$mitreMap.Print() + + $mitreMap.map['TA0043'].count | Should -Be 10 + $mitreMap.map['TA0042'].count | Should -Be 8 + $mitreMap.map['TA0001'].count | Should -Be 9 + $mitreMap.map['TA0002'].count | Should -Be 14 + $mitreMap.map['TA0003'].count | Should -Be 19 + $mitreMap.map['TA0004'].count | Should -Be 13 + $mitreMap.map['TA0005'].count | Should -Be 42 + $mitreMap.map['TA0006'].count | Should -Be 17 + $mitreMap.map['TA0007'].count | Should -Be 31 + $mitreMap.map['TA0008'].count | Should -Be 9 + $mitreMap.map['TA0009'].count | Should -Be 17 + $mitreMap.map['TA0011'].count | Should -Be 16 + $mitreMap.map['TA0010'].count | Should -Be 9 + $mitreMap.map['TA0040'].count | Should -Be 13 + } + + It 'tests some values' { + $mitreMap = [MitreMap]::new() + + $mitreMap.map['TA0043'].ContainsKey('T1597') | Should -Be $true + $mitreMap.map['TA0001'].ContainsKey('T1200') | Should -Be $true + $mitreMap.map['TA0043'].ContainsKey('T1037') | Should -Be $false + $mitreMap.map['TA0006'].ContainsKey('T1612') | Should -Be $false + } + } +} + +InModuleScope ATAPHtmlReport { + Describe 'testing functions of the class MitreMap' { + It 'tests with an example report' { + #Dummy-Data + $AuditInfos = + @{ + Id = "1.1.4" + Status = [AuditInfoStatus]::False + }, + @{ + Id = "1.2.3" + Status = [AuditInfoStatus]::True + }, + @{ + Id = "1.2.5" + Status = [AuditInfoStatus]::False + }, + @{ + Id = "1.4.5" + Status = [AuditInfoStatus]::True + } + $Subsection = @{AuditInfos = $AuditInfos } + $Section1 = @{Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + #$mitreMap.Print() + + #Tests + $mitreMap.GetType() | Should -Be "MitreMap" + $mitreMap.Map["TA0001"]["T1078"]["1.1.4"].GetType() | Should -Be 'AuditInfoStatus' + $mitreMap.Map["TA0001"]["T1078"]["1.1.4"] | Should -Be False + $mitreMap.Map["TA0006"]["T1110"]["1.2.3"] | Should -Be True + + $failedIDs = @() + foreach ($tactic in $mitreMap.Map.Keys) { + foreach ($technique in $mitreMap.Map[$tactic].Keys) { + $mitreMap.Map[$tactic][$technique].Keys | + Where-Object {$mitreMap.Map[$tactic][$technique][$_] -eq [AuditInfoStatus]::False} | + ForEach-Object { + if($failedIDs -notcontains $_){ + $failedIDs += $_ + } + } + } + } + $CISAMedigations = @() + $json = Get-Content -Raw "$PSScriptRoot\..\resources\CISToAttackMappingData.json" | ConvertFrom-Json + foreach($i in $failedIDs) { + if($null -ne $json.'CISAttackMapping'.$i.'Mitigation1' -and $CISAMedigations -notcontains $json.'CISAttackMapping'.$i.'Mitigation1'){ + $CISAMedigations += $json.'CISAttackMapping'.$i.'Mitigation1' + } + if($null -ne $json.'CISAttackMapping'.$i.'Mitigation2' -and $CISAMedigations -notcontains $json.'CISAttackMapping'.$i.'Mitigation2'){ + $CISAMedigations += $json.'CISAttackMapping'.$i.'Mitigation2' + } + } + foreach($i in $CISAMedigations) { + Write-Host $i + } + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/OrderTactics.Test.ps1 b/ATAPHtmlReport/Tests/OrderTactics.Test.ps1 new file mode 100644 index 0000000..3025a3b --- /dev/null +++ b/ATAPHtmlReport/Tests/OrderTactics.Test.ps1 @@ -0,0 +1,43 @@ +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + +InModuleScope ATAPHtmlReport { + Describe 'testing tactic order in MitreMap' { + It 'tests with an example report' { + #Dummy-Data + $AuditInfos = + @{ + Id = "1.1.4" + Status = [AuditInfoStatus]::False + }, + @{ + Id = "1.2.3" + Status = [AuditInfoStatus]::True + }, + @{ + Id = "1.2.5" + Status = [AuditInfoStatus]::False + }, + @{ + Id = "1.4.5" + Status = [AuditInfoStatus]::True + } + $Subsection = @{AuditInfos = $AuditInfos } + $Section1 = @{Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + $mitreMap.Print() + + $tactics = (Get-Content -Raw "$PSScriptRoot\..\resources\MitreTactics.json" | ConvertFrom-Json).psobject.properties.name + + #check order + $i = 0 + foreach ($tactic in $mitreMap.Map.Keys) { + $tactic | Should -Be $tactics[$i] + $i++ + } + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/Test-CompatibleMitreReport.Tests.ps1 b/ATAPHtmlReport/Tests/Test-CompatibleMitreReport.Tests.ps1 new file mode 100644 index 0000000..4f23de3 --- /dev/null +++ b/ATAPHtmlReport/Tests/Test-CompatibleMitreReport.Tests.ps1 @@ -0,0 +1,24 @@ +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + +InModuleScope ATAPHtmlReport { + Describe 'Testing Check-CompatibleMitreReport' { + It 'Testing with diffrent Reports' { + $Title = "Windows 10 Report" + $os = [System.Environment]::OSVersion.Platform + Test-CompatibleMitreReport -Title $Title -os $os | Should -Be $true + + $Title = "Windows 11 Report" + Test-CompatibleMitreReport -Title $Title -os $os | Should -Be $true + + $Title = "Windows Server 2019 Audit Report" + Test-CompatibleMitreReport -Title $Title -os $os | Should -Be $true + + $Title = "Windows Server 2022 Audit Report" + Test-CompatibleMitreReport -Title $Title -os $os | Should -Be $true + + $Title = "Windows 7 Report" + Test-CompatibleMitreReport -Title $Title -os $os | Should -Be $false + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/get-MitreLink.Tests.ps1 b/ATAPHtmlReport/Tests/get-MitreLink.Tests.ps1 new file mode 100644 index 0000000..a82bad3 --- /dev/null +++ b/ATAPHtmlReport/Tests/get-MitreLink.Tests.ps1 @@ -0,0 +1,20 @@ + +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + + +InModuleScope ATAPHtmlReport { + Describe 'Testing get-MitreLink' { + It 'tests for tactics' { + get-MitreLink -type tactics -id 'TA0001' | Should -Be 'https://attack.mitre.org/tactics/TA0001/' + get-MitreLink -type tactics -id 'TA0008' | Should -Be 'https://attack.mitre.org/tactics/TA0008/' + } + It 'tests for techniques' { + get-MitreLink -type techniques -id 'T1548' | Should -Be 'https://attack.mitre.org/techniques/T1548/' + get-MitreLink -type techniques -id 'T1119' | Should -Be 'https://attack.mitre.org/techniques/T1119/' + } + It 'tests for techniques' { + get-MitreLink -type mitigations -id 'M1047' | Should -Be 'https://attack.mitre.org/mitigations/M1047/' + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/readFromJson.Tests.ps1 b/ATAPHtmlReport/Tests/readFromJson.Tests.ps1 new file mode 100644 index 0000000..286f2b2 --- /dev/null +++ b/ATAPHtmlReport/Tests/readFromJson.Tests.ps1 @@ -0,0 +1,73 @@ + +#Import-Module +& "$PSScriptRoot\updateATAP.ps1" + +InModuleScope ATAPHtmlReport { + Describe 'Testing MitreMap' { + It 'tests correct amount of techniques per tacitc' { + $mitreMap = [MitreMap]::new() + $mitreMap.Print() + + $mitreMap.map['TA0043'].count | Should -Be 10 + $mitreMap.map['TA0042'].count | Should -Be 8 + $mitreMap.map['TA0001'].count | Should -Be 9 + $mitreMap.map['TA0002'].count | Should -Be 14 + $mitreMap.map['TA0003'].count | Should -Be 19 + $mitreMap.map['TA0004'].count | Should -Be 13 + $mitreMap.map['TA0005'].count | Should -Be 42 + $mitreMap.map['TA0006'].count | Should -Be 17 + $mitreMap.map['TA0007'].count | Should -Be 31 + $mitreMap.map['TA0008'].count | Should -Be 9 + $mitreMap.map['TA0009'].count | Should -Be 17 + $mitreMap.map['TA0011'].count | Should -Be 16 + $mitreMap.map['TA0010'].count | Should -Be 9 + $mitreMap.map['TA0040'].count | Should -Be 13 + } + + It 'tests some values' { + $mitreMap = [MitreMap]::new() + + $mitreMap.map['TA0043'].ContainsKey('T1597') | Should -Be $true + $mitreMap.map['TA0001'].ContainsKey('T1200') | Should -Be $true + $mitreMap.map['TA0043'].ContainsKey('T1037') | Should -Be $false + $mitreMap.map['TA0006'].ContainsKey('T1612') | Should -Be $false + } + } +} + +InModuleScope ATAPHtmlReport { + Describe 'testing read from json' { + It 'tests if json file is read in correctly' { + $AuditInfos = + @{ + Id = "1.1.4" + Status = [AuditInfoStatus]::False + }, + @{ + Id = "1.2.3" + Status = [AuditInfoStatus]::True + }, + @{ + Id = "1.2.5" + Status = [AuditInfoStatus]::False + }, + @{ + Id = "1.4.5" + Status = [AuditInfoStatus]::True + } + $Subsection = @{AuditInfos = $AuditInfos } + $Section1 = @{Title = "Cis Benchmarks" + SubSections = $Subsection + } + + $mitreMap = $Section1 | Where-Object { $_.Title -eq "CIS Benchmarks" } | ForEach-Object { return $_.SubSections } | ForEach-Object { return $_.AuditInfos } | Merge-CisAuditsToMitreMap + $mitreMap.Print() + + #Tests + $mitreMap.GetType() | Should -Be "MitreMap" + $mitreMap.Map["TA0001"]["T1078"]["1.1.4"].GetType() | Should -Be 'AuditInfoStatus' + $mitreMap.Map["TA0001"]["T1078"]["1.1.4"] | Should -Be False + $mitreMap.Map["TA0006"]["T1110"]["1.2.3"] | Should -Be True + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/Tests/updateATAP.ps1 b/ATAPHtmlReport/Tests/updateATAP.ps1 new file mode 100644 index 0000000..ba42701 --- /dev/null +++ b/ATAPHtmlReport/Tests/updateATAP.ps1 @@ -0,0 +1,16 @@ +#set the directory where you are programming +$dev_directory = "$PSScriptRoot\..\.." + +#deletes the old modules, if they exist +if(Test-Path "C:\Program Files\WindowsPowerShell\Modules\ATAPAuditor") { + Remove-Item -Path "C:\Program Files\WindowsPowerShell\Modules\ATAPAuditor" -recurse +} +if(Test-Path "C:\Program Files\WindowsPowerShell\Modules\ATAPHtmlReport") { + Remove-Item -Path "C:\Program Files\WindowsPowerShell\Modules\ATAPHtmlReport" -recurse +} +#copys the new modules to the module path of powershell +Copy-Item ($dev_directory + "\ATAPAuditor") -Destination "C:\Program Files\WindowsPowerShell\Modules" -recurse +Copy-Item ($dev_directory + "\ATAPHtmlReport") -Destination "C:\Program Files\WindowsPowerShell\Modules" -recurse +#imports ATAPAuditor and ATAPHtmlReport +Import-Module ATAPAuditor -Force +Import-Module ATAPHtmlReport -Force \ No newline at end of file diff --git a/ATAPHtmlReport/report.css b/ATAPHtmlReport/report.css new file mode 100644 index 0000000..f65c09e --- /dev/null +++ b/ATAPHtmlReport/report.css @@ -0,0 +1,1203 @@ +:root { + /* === Base colors === */ + /* Raw color values without semantic meaning */ + /* ! IMPORTANT " */ + --company-red: #A81A1B; + --color-white: #ffffff; + --color-black: #000000; + --color-green: #27AE60; + --color-orange: #F39C12; + --color-grey: #95A5A6; + --color-purple: #8E44AD; + --color-blue: #1900ff; + + --color-dark-gray: #d2d2d2; /* Dont ask, lightgray is darker than gray */ + --color-light-gray: #efefef; + + /* === Semantic colors === */ + /* Use these variables in layouts and components */ + /* status true in checks*/ + --status-true: var(--color-green); + /* status false in checks*/ + --status-false: var(--company-red); + /* warning in checks */ + --status-warning: var(--color-orange); + /* neutral / status none in checks */ + --status-none: var(--color-grey); + /* critical error in checks */ + --status-error: var(--color-black); + /* github grey color*/ + --github-grey: #24292e; +} + +body { + font-family: Cambria, Georgia, serif; + margin: 0; + color: default; + background-color: default; +} + +.header { + background-color: #d2d2d2; +} + +.header svg { + margin-left: 3px; + opacity: 0.8; +} + +.content { + padding: 30px 40px; +} + +a, a:visited { + color: default; +} + +html body div.header.content { + display: flex; + justify-content: space-between; + align-items: flex-start; + padding-top: 10px; + padding-bottom: 0; + font-family: "Libre Franklin", "Helvetica Neue", helvetica, arial, sans-serif; +} + +#companyName { + font-size: 2.5rem; + color: var(--company-red); + font-weight: 900; +} + +#companySlogan { + font-size: 1rem; + color: var(--color-black); + font-weight: 600; + margin: 0; + margin-bottom: 1rem; +} + +#summary > h1:nth-child(1) { + margin-bottom: 0; +} + +#logo > p:nth-child(2) { + color: #666; + margin-top: 0; +} + +#logo { + order: 2; + padding-top: px; /* No value is being set here */ +} + +#reportInformation > ul:nth-child(2) { + padding-left: 0; +} + + + +#reportInformation > ul:nth-child(2) > li:nth-child(1) { + list-style-type: none; +} + +.header svg { + margin-left: 3px; + opacity: 0.8; +} +.header svg g path:nth-child(1), /*F*/ +.header svg g path:nth-child(2), /*B*/ +.header svg g path:nth-child(6), /*G*/ +.header svg g path:nth-child(7), /*m*/ +.header svg g path:nth-child(8), /*b*/ +.header svg g path:nth-child(9) /*H*/ +{ + fill: var(--color-black); +} + +.header h1 { + margin: 0; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: 'Calibri', 'Segoe UI', sans-serif; +} + +li a { + /*display: block;*/ + font-family: Arial, sans-serif; +} + +li a:hover { + background-color: #f2f2f2; +} + +.gauge { + height: 25px; + background: var(--status-none); + border-radius: 8px; + overflow: hidden; + display: flex; +} + +.gauge .gauge-meter { + height: 100%; + flex-grow: var(--weight); + flex-shrink: 0; + flex-basis: 0; + transition: flex-grow 0.5s ease; +} + +.gauge-info { + margin: 0; + padding: 20px 0px 10px 0px; + display: flex; + justify-content: space-between; + list-style: none; +} + +.gauge-info .gauge-info-item { + flex: 1; + text-align: center; + line-height: 30px; +} + +.gauge-info .gauge-info-item span.auditstatus { + display: inline; +} + +section.collapsed > :not(:first-child) { + display: none; +} + +table { + border-collapse: collapse; + font-family: Arial, sans-serif; +} + +th, +td { + padding: 5px 10px; + text-align: left; + vertical-align: top; +} + +/* audit-info table */ +table.audit-info { + margin-left: 8%; + margin-right: 8%; + width: 90%; +} + +table.audit-info th, +table.audit-info td { + border: 1px solid #d2d2d2; +} + +table.audit-info th { + border-bottom-width: 2px; + background-color: var(--color-dark-gray); +} + +table.audit-info tr:nth-child(even) { + background-color: var(--color-light-gray); +} + +/* First column in an audit-info table */ +table.audit-info th:nth-child(1), +table.audit-info td:nth-child(1) { + text-align: left; + white-space: nowrap; + width: 40px; +} + +/* First column in an audit-info table */ +table.audit-info th:nth-child(2), +table.audit-info td:nth-child(2) { + text-align: left; + width: 50%; +} + +/* Last column in an audit-info table */ +table.audit-info th:last-child, +table.audit-info td:last-child { + text-align: center; + width: 70px; +} + +.error, +.passed, +.green, +.failed, +.red { + color: var(--color-white); +} + +.warning, +.orange { + color: var(--color-black); +} + +.passed, +.green { + background-color: var(--status-true); +} + +.failed, +.red { + background-color: var(--status-false); +} + +.warning, +.orange { + background-color: var(--status-warning); +} + +.none, +.grey { + background-color: var(--status-none); +} + +.error { + background-color: var(--status-error); +} + +h1 span.passed, +h1 span.failed, +h1 span.warning, +h2 span.passed, +h2 span.failed, +h2 span.warning, +h3 span.passed, +h3 span.failed, +h3 span.warning { + padding: 5px 10px; + border-radius: 8px; +} + +span.auditstatus { + display: block; + padding: 5px 10px; + border-radius: 8px; + font-weight: bold; + margin: auto; +} + +.sectionAction { + display: inline-block; + text-align: center; + text-decoration: none; + margin: 0 0 0 15px; + padding: 0 8px; + color: var(--color-black); + background-color: var(--color-dark-gray); + border-radius: 8px; + font-weight: bold; + cursor: pointer; + transition-duration: 500ms; +} + +.sectionAction:hover { + background-color: var(--color-light-gray); + /* color: var(--color-blue); */ +} + +#host-information { + float: left; +} + +/* Overall compliance donut chart */ + +.card { + float: right; + margin: 0 100px 0 0; + width: 250px; +} + +.donut-chart { + position: relative; + border-radius: 50%; + overflow: hidden; +} + +.donut-chart.chart { + width: 200px; + height: 200px; + background: #c6c9cc; +} + +.donut-chart .slice { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.donut-chart .chart-center { + position: absolute; + border-radius: 50%; + top: 25px; + left: 25px; + width: 150px; + height: 150px; + background: var(--color-white); +} + +.donut-chart .chart-center span { + display: block; + text-align: center; + font-size: 40px; + line-height: 150px; + color: var(--color-black); +} + + +#navigationButtons { + margin-top: 15px; + display: grid; + grid-template-rows: 50px; + grid-template-columns: repeat(6, 160px); +} + +.navButton{ + transition-duration: 500ms; + background-color: transparent; +} +.navButton:hover{ + transition-duration: 500ms; + background-color: var(--color-light-gray); +} + +.selectedNavButton{ + transition-duration: 500ms; + background-color: var(--color-orange) !important; +} + +button { + margin-left: 10px; + border-radius: 8px; + font-weight: bold; +} + +#riskScore { + font-family: Arial, sans-serif; + text-align: center; +} + +#CISA, +#MITRE { + font-family: Arial, sans-serif; +} + +#CISATable { + margin-right: 15%; + width: 85%; + border-collapse: collapse; + border: 1px solid var(--color-white); + font-family: Arial, sans-serif; +} + +.CISAMitigations { + width: 60%; +} + +.CISAMitreTechniqueIDs { + width: auto; + line-height: 1.5; +} + +.CISAMitreTechniqueIDs a { + border-radius: 0.3em; + background-color: #cc0000; + color: var(--color-white); + padding: 0.2em; + margin: 0.2em; + text-decoration: none; +} + +.CISAMitigationIDs { + width: auto; +} + +.CISAMitigationIDs a { + color: #000000; + text-decoration: none; +} + +#CISAthead { + border-bottom-width: 2px; + background-color: var(--color-dark-gray); + border: 1px solid #d2d2d2; +} + +#CISAtbody tr:nth-child(even) { + background-color: var(--color-light-gray); + border: 1px solid #d2d2d2; +} + +#CISAtbody tr td { + border: 1px solid #d2d2d2; +} + + +#MITRETable { + width: 100%; + border-collapse: collapse; + border: 1px solid var(--color-white); + font-family: Arial, sans-serif; + display: flex; + flex-direction: column; +} + +#MITREthead a { + color: var(--color-black); + text-decoration: none; + font-weight: bold; +} + +#MITREtbody a { + color: var(--color-black); + text-decoration: none; +} + +#MITREtbody tr, +#MITREthead tr { + display: flex; +} + +#MITREtbody td, +#MITREthead td { + min-width: 75px; + border: 1px solid #cccccc; + padding: 6px; + flex: 1; + flex-basis: 0; +} + +#MITREthead td { + overflow: hidden; + overflow-wrap: break-word; +} + +.MITRETechnique { + padding: 6px; + border: 1px solid var(--color-black); +} + +.tooltip { + position: relative; + display: inline-block; + border-bottom: 1px dotted var(--color-black); +} + +.tooltip .tooltiptext { + visibility: hidden; + width: 120px; + background-color: var(--color-black); + color: var(--color-white); + text-align: center; + border-radius: 6px; + padding: 5px 0; + + /* Position the tooltip */ + position: absolute; + z-index: 1; +} + +.tooltip:hover .tooltiptext { + visibility: visible; +} + +#Tip p { + font-weight: bold; + padding: 5px; +} + +.square-container { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 10px; +} + +.square { + width: 20px; + height: 20px; + border: 1px solid var(--color-black); +} + +#riskMatrixContainer { + display: grid; + position: relative; + grid-template-columns: 100px repeat(5, 60px); + grid-template-rows: repeat(6, 60px); + left: 10%; + float: left; + margin-top: 50px; + text-align: center; +} + +#riskMatrixContainer div { + border: 1px solid var(--color-black); +} + + +#severity { + grid-column-start: 1; + grid-column-end: 2; + grid-row-start: 1; + grid-row-end: 7; + position: relative; +} + +#quantity { + grid-column-start: 2; + grid-column-end: 7; + grid-row-start: 6; + grid-row-end: 7; + position: relative; +} + +#severityArea { + text-align: center; + position: absolute; + margin: 0; + top: 50%; + left: 20%; +} + +#quantityArea { + text-align: center; + position: absolute; + margin: 0; + top: 35%; + left: 40%; +} + +#severityCritical { + grid-column-start: 2; + grid-column-end: 3; + grid-row-start: 1; + grid-row-end: 2; + padding-top: 20px; +} + +#severityHigh { + grid-column-start: 2; + grid-column-end: 3; + grid-row-start: 2; + grid-row-end: 3; + padding-top: 20px; +} + +#severityMedium { + grid-column-start: 2; + grid-column-end: 3; + grid-row-start: 3; + grid-row-end: 4; + padding-top: 20px; +} + +#severityLow { + grid-column-start: 2; + grid-column-end: 3; + grid-row-start: 4; + grid-row-end: 5; + padding-top: 20px; +} + +#quantityCritical { + grid-column-start: 6; + grid-column-end: 7; + grid-row-start: 5; + grid-row-end: 6; + text-align: center; + padding-top: 20px; +} + +#quantityHigh { + grid-column-start: 5; + grid-column-end: 6; + grid-row-start: 5; + grid-row-end: 6; + text-align: center; + padding-top: 20px; +} + +#quantityMedium { + grid-column-start: 4; + grid-column-end: 5; + grid-row-start: 5; + grid-row-end: 6; + text-align: center; + padding-top: 20px; +} + +#quantityLow { + grid-column-start: 3; + grid-column-end: 4; + grid-row-start: 5; + grid-row-end: 6; + text-align: center; + padding-top: 20px; +} + +#riskMatrixContainer:nth-child(10) { + position: relative; +} + +#riskMatrixSummary:nth-child(10) { + position: relative; +} + +/* Color for each Risk */ +#medium_medium, +#medium_low, +#low_medium { + background-color: #ffc000; +} + +#high_low, +#high_medium, +#high_high, +#medium_high, +#low_high { + background-color: red; +} + +#critical_low, +#critical_medium, +#critical_high, +#critical_critical, +#high_critical, +#medium_critical, +#low_critical { + background-color: purple; +} + + +/* Low Risk */ +#low_low { + background-color: #548dd6; + grid-column-start: 3; + grid-column-end: 4; + grid-row-start: 4; + grid-row-end: 5; +} + +/* Medium Risk */ +#medium_low { + grid-column-start: 3; + grid-column-end: 4; + grid-row-start: 3; + grid-row-end: 4; +} + +#medium_medium { + grid-column-start: 4; + grid-column-end: 5; + grid-row-start: 3; + grid-row-end: 4; +} + +#low_medium { + grid-column-start: 4; + grid-column-end: 5; + grid-row-start: 4; + grid-row-end: 5; +} + +/* High Risk*/ +#high_low { + grid-column-start: 3; + grid-column-end: 4; + grid-row-start: 2; + grid-row-end: 3; +} + +#high_medium { + grid-column-start: 4; + grid-column-end: 5; + grid-row-start: 2; + grid-row-end: 3; +} + +#high_high { + grid-column-start: 5; + grid-column-end: 6; + grid-row-start: 2; + grid-row-end: 3; +} + +#medium_high { + grid-column-start: 5; + grid-column-end: 6; + grid-row-start: 3; + grid-row-end: 4; +} + +#low_high { + grid-column-start: 5; + grid-column-end: 6; + grid-row-start: 4; + grid-row-end: 5; +} + +/* Critical Risk */ +#critical_low { + grid-column-start: 3; + grid-column-end: 4; + grid-row-start: 1; + grid-row-end: 2; +} + +#critical_medium { + grid-column-start: 4; + grid-column-end: 5; + grid-row-start: 1; + grid-row-end: 2; +} + +#critical_high { + grid-column-start: 5; + grid-column-end: 6; + grid-row-start: 1; + grid-row-end: 2; +} + +#critical_critical { + grid-column-start: 6; + grid-column-end: 7; + grid-row-start: 1; + grid-row-end: 2; +} + +#high_critical { + grid-column-start: 6; + grid-column-end: 7; + grid-row-start: 2; + grid-row-end: 3; +} + +#medium_critical { + grid-column-start: 6; + grid-column-end: 7; + grid-row-start: 3; + grid-row-end: 4; +} + +#low_critical { + grid-column-start: 6; + grid-column-end: 7; + grid-row-start: 4; + grid-row-end: 5; +} + +#severityDetails { + margin-left: 8%; + margin-top: 30px; + border: 1px solid #d2d2d2; + margin-right: 8%; + float: right; + margin-bottom: 40px; +} + +#severityDetails td { + border: 1px solid #d2d2d2; +} + +#calculationTables { + float: right; + position: relative; +} + +.calculationTablesText { + text-align: left; + font-family: Arial, sans-serif; +} + +#riskScore th { + background-color: var(--color-dark-gray); +} + +#riskScore tr:nth-child(2n) td { + background-color: var(--color-light-gray); +} + + +#riskMatrixSummary { + font-family: Arial, sans-serif; + display: grid; + position: relative; + grid-template-columns: 100px repeat(5, 60px); + grid-template-rows: repeat(6, 60px); + right: 10%; + float: right; +} + +#riskMatrixSummary div { + border: 1px solid var(--color-black); +} + +#riskMatrixSummaryArea { + float: right; + text-align: center; + margin-right: 10%; +} + +/* System Information Content */ +.systemInformationContent>tr>th { + padding-left: 0; + padding-right: 0; +} + + +#testGrid { + display: grid; + grid-auto-rows: minmax(auto, auto); + row-gap: 2px; + column-gap: 2px; + font-family: 'Calibri', 'Segoe UI', sans-serif; + word-break: break-word; + white-space: normal; + align-items: start; +} + +#testGrid div { + grid-auto-rows: minmax(auto, auto); + border: 1px solid #d2d2d2; + padding: 4px 6px; + font-size: 18px; + font-family: 'Calibri', 'Segoe UI', sans-serif; + box-sizing: border-box; + overflow-wrap: anywhere; + background-clip: padding-box; + height: 100%; + align-self: stretch; +} + + +#systemData { + display: grid; + grid-template-columns: repeat(4, 100px); + grid-template-rows: repeat(10, 5%); +} + +#hardwareInformation td { + width: min-content; +} + +#systemInformation { + grid-column-start: 1; + grid-column-end: 2; + grid-row-start: 0; + grid-row-end: 1; + margin-top: 0px; +} + +#hardwareInformation { + grid-column-start: 1; + grid-column-end: 2; + grid-row-start: 1; + grid-row-end: 1; +} + +#softwareInformation { + grid-column-start: 2; + grid-column-end: 3; + grid-row-start: 1; + grid-row-end: 2; +} + +/* Dot Indicators (Positioning must be precise) */ +#dotRiskScoreTab, #dotSummaryTab { + height: 15px; + width: 15px; + background-color: var(--color-black); + border-radius: 50%; + border-style: dotted; + display: inline-block; + position: absolute; + left: 22px; + top: 22px; /* Using a single top/left definition for both */ +} + + + +/* Quantity and Severity Results Blocks */ +#quantityTable, #severityTable { + margin-right: auto; + margin-top: 30px; + border: 1px solid var(--color-black); +} + +.severityResultFalse, +.severityResultTrue, +.severityResultNone, +.severityResultError, +.severityResultWarning{ + display: block; + padding: 5px 10px; + border-radius: 8px; + font-weight: bold; + margin: auto; +} + +.severityResultFalse { + background-color: var(--status-false); + color: var(--color-white); +} + + +.severityResultTrue { + background-color: var(--status-true); + color: var(--color-white); +} + +.severityResultNone{ + background-color: var(--status-none); + color: var(--color-black); +} + +.severityResultError { + background-color: var(--status-error); + color: var(--color-light-gray); +} + +.severityResultWarning { + background-color: var(--status-warning); + color: var(--color-black); +} + +.tabContent#riskScore { + text-align: left; +} + +#severityCompliance { + margin-top: 25%; + clear: both; +} + +#complianceStatus { + padding: 5px 10px; + border-radius: 8px; + color: var(--color-white); + margin-left: 6%; + font-weight: bold; + display: inline; +} + +#referencesContainer { + display: grid; + grid-template-rows: 280px; + grid-template-columns: repeat(2, 500px); +} + +#referencesContainer div { + text-align: center; + margin-left: auto; + margin-right: auto; +} + + +#settingsOverview section { + margin-left: 2%; + margin-right: 5%; +} + +#invalidOS { + display: inline; + padding: 5px 10px; + border-radius: 8px; + font-weight: bold; + margin: auto; + background-color: #777777; +} + +#references p, #summary p, #settingsOverview p { + font-family: Arial, sans-serif; +} + +#foundationData p { + font-family: Arial, sans-serif; +} + +#foundationData section { + margin-left: 2%; + margin-right: 5%; +} + + +#hashTableDiv { + float: right; + width: 60%; + margin-bottom: 30px; +} + +#hashTableBody td { + line-height: 0px; + vertical-align: middle; +} + +#hashTable thead tr th { + vertical-align: middle; +} + +#CurrentATTCKHeatmap { + display: grid; + grid-template-columns: 20% 20% 20% 20% 20%; + grid-template-rows: 20% 20% 20% 20% 20%; + margin-top: 30px; + border: 1px solid var(--color-black); + margin-right: auto; + +} + +@media only screen and (max-width: 1900px) { + #hashTableBody td { + line-height: 17px; + vertical-align: middle; + } +} + +/* Two-column layout with flexible wrapping in the About Us section*/ +.columns-container { + display: flex; + flex-wrap: wrap; + gap: 40px; + align-items: flex-start; + justify-content: space-around; + text-align: left; + overflow-wrap: break-word; +} + +/* Left column takes about 2/3 of space */ +.left-column { + flex: 2; + min-width: 300px; +} + +/* Right column takes about 1/3 of space */ +.right-column { + flex: 1; + min-width: 300px; +} + +/* Responsive video container */ +.video-wrapper { + width: 100%; + max-width: 480px; + aspect-ratio: 16 / 9; + margin: 20px 0; +} + +.video-wrapper iframe { + width: 100%; + height: 100%; + border: none; +} + +/*bulletpoint list in the right column*/ +.hardening-ul { + font-family: "Libre Franklin", "Helvetica Neue", helvetica, arial, sans-serif; + line-height: 1.6; + margin: 0 auto; + padding: 0 20px; +} + +/* Product section layout */ +.product-block { + display: flex; + flex-wrap: wrap; + justify-content: center; + padding: 20px 0; + margin-bottom: 20px; +} + +.product-item { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + min-width: 180px; +} + +/* Contact section background and padding */ +.contact-block { + background-color: var(--color-white); + padding: 20px 0; +} + +/* Flexbox for contact items */ +.contact-flex { + display: flex; + justify-content: space-between; + gap: 30px; + margin: 0 auto; + line-height: 1.2; + padding: 0 20px; + box-sizing: border-box; +} + +/* Flexbox in columns for p elements in each contact-item*/ +.contact-item { + display: flex; + flex-direction: column; + align-items: flex-start; + text-align: left; + flex: 1; + margin: 5px 0; +} + +/* Compact spacing between paragraphs only in this contact item context*/ +.contact-item p { + margin: 4px 0; +} + +/* Button container aligned with contact section */ +.contact-buttons { + display: flex; + gap: 20px; + justify-content: flex-start; + margin-top: 20px; + max-width: 1200px; + margin-left: auto; + margin-right: auto; + padding: 0 20px; + box-sizing: border-box; +} + +/* Base button style inside contact section */ +.contact-buttons .button-base { + border-radius: 4px; + padding: 15px 25px; + margin-left: 0px; + color: var(--color-white); + box-shadow: 2px 2px var(--color-black); + border: none; + cursor: pointer; + font-size: 16px; + height: auto; +} + +/* Contact Us button, that uses the company red color */ +#contactUsButton { + background-color: var(--company-red); +} + +/*GitHub button, that uses the dark color of the GitHSub website*/ +#githubButton { + background-color: var(--github-grey); +} + +/*this is the link of the company logo in the top right corner*/ +#companyLink { + text-decoration: none; + cursor: pointer; +} \ No newline at end of file diff --git a/ATAPHtmlReport/report.js b/ATAPHtmlReport/report.js new file mode 100644 index 0000000..b73560a --- /dev/null +++ b/ATAPHtmlReport/report.js @@ -0,0 +1,278 @@ +"use strict"; + +let AmountOfNonCompliantRules; +let AmountOfCompliantRules; +let TotalAmountOfRules; +let QuantityCompliance; + +let TotalAmountOfSeverityRules; +let AmountOfFailedSeverityRules; +let SeverityCompliance; + + +const cssVars = getComputedStyle(document.documentElement); + +const COLORS = { + green: cssVars.getPropertyValue('--color-green').trim(), + red: cssVars.getPropertyValue('--company-red').trim(), + orange: cssVars.getPropertyValue('--color-orange').trim(), + purple: cssVars.getPropertyValue('--color-purple').trim(), + white: cssVars.getPropertyValue('--color-white').trim(), + blue: cssVars.getPropertyValue('--color-blue').trim(), + dark_gray: cssVars.getPropertyValue('--color-dark-gray').trim(), + light_gray: cssVars.getPropertyValue('--color-light-gray').trim() +}; + +function startConditions() { + let isRiskScoreValue = document.getElementById("riskScore"); + let isMITREValue = document.getElementById("MITRE"); + + /* Default-Value: Display summary always at the beginning */ + document.getElementById("summary").style.display = "block"; + + /* Default-Value: Disable all other tabs at the beginning */ + document.getElementById("foundationData").style.display = "none"; + document.getElementById("references").style.display = "none"; + document.getElementById("settingsOverview").style.display = "none"; + + + /* document.getElementById("summaryBtn").style.backgroundColor = COLORS.orange; + document.getElementById("foundationDataBtn").style.backgroundColor = 'transparent'; + document.getElementById("referenceBtn").style.backgroundColor = 'transparent'; + document.getElementById("settingsOverviewBtn").style.backgroundColor = 'transparent'; */ + + if (isRiskScoreValue != null) { + document.getElementById("riskScore").style.display = "none"; + /* document.getElementById("riskScoreBtn").style.backgroundColor = 'transparent'; */ + /* Initialize necessary variables */ + + AmountOfNonCompliantRules = document.getElementById("AmountOfNonCompliantRules").textContent; + AmountOfCompliantRules = document.getElementById("AmountOfCompliantRules").textContent; + TotalAmountOfRules = document.getElementById("TotalAmountOfRules").textContent; + QuantityCompliance = document.getElementById("QuantityCompliance").textContent; + TotalAmountOfSeverityRules = document.getElementById("TotalAmountOfSeverityRules").textContent; + AmountOfFailedSeverityRules = document.getElementById("AmountOfFailedSeverityRules").textContent; + + calcDotPosition(); + let severityComplianceCollapseBtn = document.getElementById("severityComplianceCollapse"); + severityComplianceCollapseBtn.addEventListener("click", () => { + if (document.getElementById("severityDetails").style.display == "none") { + document.getElementById("severityDetails").style.display = "block"; + } + else { + document.getElementById("severityDetails").style.display = "none"; + } + }) + } + + if (isMITREValue != null) { + document.getElementById("MITRE").style.display = "none"; + document.getElementById("MITREBtn").style.backgroundColor = 'transparent'; + document.getElementById("CISA").style.display = "none"; + document.getElementById("CISABtn").style.backgroundColor = 'transparent'; + } +} + + +let buttonNumber; + +function clickButton(value) { + buttonNumber = parseInt(value); + + /* Disable all content */ + let tabContents = document.getElementsByClassName('tabContent'); + for (let i = 0; i < tabContents.length; i++) { + tabContents.item(i).style.display = "none"; + } + + /* Disable all buttons */ + let buttons = document.getElementsByClassName('navButton'); + for (let i = 0; i < buttons.length; i++) { + /* buttons.item(i).style.backgroundColor = 'transparent'; */ + buttons.item(i).classList.remove("selectedNavButton"); + } + + + + /* Re-Enable fitting content / button */ + switch (buttonNumber) { + case 1: + document.getElementById("summary").style.display = "block"; + /* document.getElementById("summaryBtn").style.backgroundColor = COLORS.orange; */ + document.getElementById("summaryBtn").classList.add("selectedNavButton"); + break; + case 2: + document.getElementById("riskScore").style.display = "block"; + /* document.getElementById("riskScoreBtn").style.backgroundColor = COLORS.orange; */ + document.getElementById("riskScoreBtn").classList.add("selectedNavButton"); + calcDotPosition(); + break; + case 3: + document.getElementById("references").style.display = "block"; + /* document.getElementById("referenceBtn").style.backgroundColor = COLORS.orange; */ + document.getElementById("referenceBtn").classList.add("selectedNavButton"); + break; + case 4: + document.getElementById("settingsOverview").style.display = "block"; + /* document.getElementById("settingsOverviewBtn").style.backgroundColor = COLORS.orange; */ + document.getElementById("settingsOverviewBtn").classList.add("selectedNavButton"); + break; + case 5: + document.getElementById("foundationData").style.display = "block"; + /* document.getElementById("foundationDataBtn").style.backgroundColor = COLORS.orange; */ + document.getElementById("foundationDataBtn").classList.add("selectedNavButton"); + break; + case 6: + document.getElementById("MITRE").style.display = "block"; + /* document.getElementById("MITREBtn").style.backgroundColor = COLORS.orange; */ + document.getElementById("MITREBtn").classList.add("selectedNavButton"); + break; + case 7: + document.getElementById("CISA").style.display = "block"; + /* document.getElementById("CISABtn").style.backgroundColor = COLORS.orange; */ + document.getElementById("CISABtn").classList.add("selectedNavButton"); + break; + } + +} + + + +/* +Calculate the position of the dot inside the risk matrix; +Will be calleed, after the user has clicked on Risk Score Button +*/ +function calcDotPosition() { + + + let dotRiskScoreTab = document.getElementById("dotRiskScoreTab"); + let dotSummaryTab = document.getElementById("dotSummaryTab"); + QuantityCompliance = parseFloat(QuantityCompliance); + + let complianceValueQuantity = 0; + let complianceValueSeverity = 0; + + /*low quantity compliance*/ + if (80 < QuantityCompliance) { + dotRiskScoreTab.style.gridColumnStart = 3; + dotSummaryTab.style.gridColumnStart = 3; + complianceValueQuantity = 1; + } + /*medium quantity compliance*/ + else if (65 < QuantityCompliance && QuantityCompliance < 80) { + dotRiskScoreTab.style.gridColumnStart = 4; + dotSummaryTab.style.gridColumnStart = 4; + complianceValueQuantity = 2; + } + /*high quantity compliance*/ + else if (50 < QuantityCompliance && QuantityCompliance < 65) { + dotRiskScoreTab.style.gridColumnStart = 5; + dotSummaryTab.style.gridColumnStart = 5; + complianceValueQuantity = 3; + } + /*critical quantity compliance*/ + else { + dotRiskScoreTab.style.gridColumnStart = 6; + dotSummaryTab.style.gridColumnStart = 6; + complianceValueQuantity = 4; + } + + + SeverityCompliance = parseInt(AmountOfFailedSeverityRules); + /*low severity compliance*/ + if (SeverityCompliance == 0) { + dotRiskScoreTab.style.gridRowStart = 4; + dotSummaryTab.style.gridRowStart = 4; + complianceValueSeverity = 1; + + + document.getElementById("complianceStatus").style.backgroundColor = COLORS.green; + } + /*critical severity compliance*/ + else { + dotRiskScoreTab.style.gridRowStart = 1; + dotSummaryTab.style.gridRowStart = 1; + complianceValueSeverity = 4; + document.getElementById("complianceStatus").style.backgroundColor = COLORS.red; + } + /* Unhide the dot now that it has been positioned */ + document.getElementById("dotSummaryTab").style.display = "inline-block"; + + let totalComplianceValue = Math.max(complianceValueQuantity, complianceValueSeverity); + + let summary = "Current Risk Score on tested System: "; + let riskResult = document.createElement("p"); + riskResult.style.display = "contents"; + if (totalComplianceValue == 1) { + riskResult.innerText = "Low"; + riskResult.style.backgroundColor = "#548dd6"; + } + else if (totalComplianceValue == 2) { + riskResult.innerText = "Medium"; + riskResult.style.backgroundColor = "#ffc000"; + } + else if (totalComplianceValue == 3) { + riskResult.innerText = "High"; + riskResult.style.color = "white"; + riskResult.style.backgroundColor = "#cc0000"; + } + else { + riskResult.innerText = "Critical"; + riskResult.style.color = "white"; + riskResult.style.backgroundColor = "purple"; + } + riskResult.style.display = "inline"; + riskResult.style.padding = "5px 10px"; + riskResult.style.borderRadius = "8px"; + riskResult.style.fontWeight = "bold"; + riskResult.style.margin = "auto"; + + let copyRiskResult = riskResult.cloneNode(); + copyRiskResult.innerText = riskResult.innerText; + + document.getElementById("CurrentRiskScore").textContent = summary; + document.getElementById("CurrentRiskScore").appendChild(riskResult); + document.getElementById("CurrentRiskScoreRS").textContent = summary; + document.getElementById("CurrentRiskScoreRS").appendChild(copyRiskResult); + +} + +/* +techniques are hidden or shown based on the status of the provided checkboxes and classes +classes must be in a compatible format for document.querySelectorAll() +examples with first all nodes in the 'orgMeasure' class and second all nodes that are in the 'MITRETechnique' but not in the 'mailVector' class: +hideMitreTechniques(this, '.orgMeasure') +hideMitreTechniques(this, '.MITRETechnique:not(.mailVector)') +*/ +let activeFilter = new Array(); +function hideMitreTechniques(checkbox, classes) { + let classElements = document.querySelectorAll(classes); + if (checkbox.checked) { + /* push the current classes into the activeFilter array to determine which filters are currently active. */ + activeFilter.push(classes); + for (let i = 0; i < classElements.length; i++) { + classElements[i].style.padding = '0.1em'; + + const children = classElements[i].querySelectorAll('*'); + for (let j = 0; j < children.length; j++) { + children[j].style.display = 'none'; + } + } + } + else { + activeFilter.splice(activeFilter.indexOf(classes), 1); + /* create an array from the classElements since it makes filtering easier. */ + let elementsToHide = Array.from(classElements); + /* create an array that includes all elements from the remaining active filters */ + let elementsNotToHide = (activeFilter.length === 0) ? new Array() : Array.from(document.querySelectorAll(activeFilter)); + /* filter the elementsToHide array to retrieve and display only the elements that are not hidden by other filters */ + elementsToHide = elementsToHide.filter(element => !elementsNotToHide.includes(element)); + for (let i = 0; i < elementsToHide.length; i++) { + elementsToHide[i].style.removeProperty('padding'); + const children = elementsToHide[i].querySelectorAll('*'); + for (let j = 0; j < children.length; j++) { + children[j].style.removeProperty('display'); + } + } + } +} \ No newline at end of file diff --git a/ATAPHtmlReport/resources/CISToAttackMappingData.json b/ATAPHtmlReport/resources/CISToAttackMappingData.json new file mode 100644 index 0000000000000000000000000000000000000000..86c1c727b94ffed7f75b56ab69001089aeece563 GIT binary patch literal 518728 zcmeFaeQz8`*5z4$53t{%AYc|Uo|YepqGa~~3qxxg`*ipb1}Vq_^HP$Y|$QBhfO;@o@gOZaX<|d89tVa&c$z<>Ger#b0$6ud6xi$m2VUyNg@${VVzZj{JOM z@t4}WaWi`;bH9+;9W7pXGkYX6+pFgBZgD6x{~*u#uy`Zybh-Gox&ue@`zLvnncSBD zpUBmh)w?{C=fA7QT*`ZUy?8HQ`Wj1_*PX@p^0iz%lt)ix?6->(`Rn=OH<@AcU2;cx zpLgUs-fj0g-KpLw|KC~MTk}pI$&63r^W*b+w|G^}OFxPKyYt?-d({7K>{V;xRPO36 zdA;}Y%BS*v`@L&E-8;eee0%Zr%J)3<9q{?2dI#%1wL9|u)_-b4-@z1C* zJ3ZE&;&Ugs>h3Id6R)~G!N>XH_v(N4iQBR^{@P>a>=So`y9B%9o#cpV&wWSU!Rr02 zy>II~<|=k=-OIScJ_Ff$`G0DU{##zhf7T6Q5cci|vID_OhqANQ*3+-3v+j8| zmmBg*ujMt^QGI69QC6{zyBdBttoG#-`HB5fcjxw4I-~k~wQ=nGjm67~tKP_LU>)Px zXVtq2UAt~B`!eEXZA=h&vG^#j$G-kI`RR7`$$eE}^NqZxb9ra{4aT{Uf1j$yj^vTI zGTMcV$8-LuUAwIQvXsAKT`a5T)JNYDVMD&gBtyls^Ow?8dL;6+zXh;D+zFYp)T$d+n9&R^^Nk#fU=)UdL*m$RTQT z46@n}a!T_WLxjfTf2b zb1AlqZ-<3B123kH32Yz~32bLoG|I$>T4ngqw|u(gQ%p}_M9zaPnWJd0r%Aiml5SKuJLQ+$;io=U8Tu^DV!r|!#2G=!Cd zjTo#=0UP-5L^Cer`v*Zz-G7Mj=DQVO(DA!q4ttI03z$5XuT%LMB!V0A0xqx6vk9em z#uR#+#!-mdj-@N+*)Y-XYBi#{p?jkVB> z$3hlW3}XBlg~ls~g+L9S%cF{Mjs!*6Yws$S(Cj;OETWLaOHkGLpLqPaSXwA*WXz$Z z!7JzjeNpsW7-(7L+|?tUVY|O=XPLe3^sN}hvOSL3HWup$eV$z&h?`3)P1$DC&zG@v zY42&6y_N$hFO7QVkut08t3VdJc~90;3=^@du2DxmyAp4fTyJDJuFORQ^Fw5kR~I>`?srv(I@ z^h8%a-nl2y)RR7*FMqCskJ2bNRk6RS_@bacVc} z&+umw-u2tqaP|}#X1kIT9kZ_6R+h0gTvfT`juR(o|h?o_&W8ffDnqV$7jORiOEgN%~qyF z#H^`&7#o*=kON~=$v>b*l_)Bi2Ke|^-=nG=RYOEpHFFJ*3a#K>Vifs!4BId56Kb#%VUq@N-usT{PDhlfYhqjYVQQQYkk~?XXK3J5G{>~Q|IQTvQSoDF2TC) zX)ed2Jd|n90KL`7#nEa6GONik(A+hjd-@_TAN$bHY#c5u&*rYgO2aln7ju}sb3^tB zl=dmcIkiJqY5q=(U9mYVJ*vEYJeXrqmcd0ms-oGU=JlYbort|gZ30mm;-1tN{MLxp zgx6eqPj@ShDF3}ee3n$)U^xdvZLjiT_Uk%LmcN7DC*tg$m$%ziQ}O{cw^R3HL_&7AbjU z=h}Ityoh_8+BXd(XdQ}WboncpXgq#pEL-^3j<>G1O?fg*4z;ezi>A~0I{Z18jDmF; z!PmL=XIsd(h3K+gT2w>l6!P0jUi&HYe*0l%vtC799ph$v^f32*zEs|mCExUy$pcoTysEtJW|h9xiQ$t|tMB)f_id}N29_`Gv29WJ zaaNh;5toLisl?mA74O1MpCIN(rM{lmM9zt;)+djPsE4ac@pFdzA!Bpu@IBFTV(jDG z%ro8CAg6?W(f*H*u zCSF3dmgcCqu4Mcb=AxsFc4s15GOTmvI(Aa8X?TTy?o6?5vkX(@WA0R)Z%VTdr&7uP zRPaPMW_K>d#?RWqDJffzFd4Kv!b^8 ztQKDy&w6u*4Z3&fIc>uf^_?m=pfqg8)P9#>U6K`WP^leG^*9ww+M{R~7E_|?8Ejg= z^>q03M;ebQB2Fdb^Gw-eD=%vyE=Q{rOlkiBt6D=bgyrh}rTkSN=C^!W;LJheIjFqc zhPZr>Rd|Wf9)A*Upv&`#{KIGRPt)C(^&WeIEgXdXXFbxj&j#mbuFvfm)1}78-gw5j zE&f4_p0pY5BJPv#QbC$Z%211}yc~x(4R>>B2-O0t!o=z6@!oF&by++EjZwr!HGhb5+(^RmOX(K_Eh?M_c$<`{0=%uavZ zc?fq4tku^!h1Pi)82KPJ(>sZf(rXq()GPF<_##h%ECPQOhw+flSAZj8`czG2{ijfe z?^ZiPSqhZSX?iH2I`UlniBGcfQH=F0KNKkR*V8LcgD&QJ#*)^!^h3wy*aFWwMy1~j zT6UwVsPg#*cMHq|&^b*3CocsJ=fV}lM>zZ9cln9RFMMxwr31kTaZ5aLxP-p01dQVr zvRj_Z`4;VNNJQxImiDR{SWNPJVL@t~{Ta*{B#YuSLhZ@PW94-bxEp2v*4O{_U=S>y zRo=f^aoPdXKXC?afXF=BfL0@Dk3Sy=VI-E5{W)iyxjrt|JK%0*2b9KRF}6u57=jt_ zm$3er?|QyIj4;=Ng@{87$hpur#iTsk64`n6O@sD%NSPxX-pq0T!dJ43UoxXT+mK+@v&;fm>(eaPOwuI&2H_htdH!RIh zG9S3F|IEUBW83?2D_`~XI1IJNv2|)37N;l0U{PyWLOXQVNH(Y8H8h68@ip4HP#BY0 zTPg}&7tWcjOyR13heg;8=!)&?Z5?J))nlh(tMT#KTsWCZb#|AP_e?(jlWH9(S9Eu( zwVpiYQ(>*aJ#ZYgHW%{mQ^hz(@{@Jx!J?#JFZmMqXv#&(MEw6=^6z~13hU-ie@ z;%&($WA%sFU^PD(7lcOG4DM_;!~H5W&vD8`F2u#Cv72M2P)$J>?(ig8%bG=WAQl@a zJe4neDeXC;7F^xe^6@fct-Adkn{4)vnw;o+@8ct>xz>MKRnFtrKj(62&-A9XHm`S9 zXt%9qK1d1+i*;{%!#F)4#&_?dquIuuVD3TwD-=sdH9IDUW=`)nxOG|_&AFVoY;;~9)e?bh4K*G6|MDqC$j#v3LDfb z^6+YSoY)h3y7?=HMpNY46?hJneO1A{D*B8wt53zA+fBxlF}gt?rnH$&fhivgM_DeZ z#hcz&3c)A&3;MNkm(^W>Ev?n#Z?FG6P1kicr7lUMNZRc~5!sKeR>!>j?4_rIYUNmb zGZ>nDz&u$N@x5%QL^+dxYA+1&4UIjFheGRUy^fJ@=3TGbocl1<0|ePf<2W=2w#RU2 z%(d(Gnm&C++SrEKHER~+n3_nghTo@{m8+3tb^=|;T0O$ginwvTuyX2$Wu4|2ml2l_ zN%xbnWQ^9aZsj)fGHhm{-K_*`^s#t#R$*v8tf)&ruXI_gzGL|!_X5OVccLm1asES? z0Hmo`NIllE`~`2*dKkl4oZp3xPv#W)?Al2PZ}Mg}Ce^@y$TeRSrPJ?@%;`wOZyF!l zjfxrM#aSB0%7L>O*4Yl6#pCLeU=Eb34n*Ya-Id)sqYPV`$e<~arfimgvNU-bIZ!s0 zJdOTrHiWlkeEBi0?#Mxj_)3%Ckpo{bzT7le%w^hY=L+mUd@F3hdYrkP*Ws+iV|jjA z3gvC-_fk%Gr0eVhi9(5olO}f~2b#*t-B=yVThCVX+54wp=R`Dqy29Y4^+VHvcx118 z`c?EHG@tH`T#Z&rmM?xAej2r2uVhAeey3td@%?t~HHPSdjx98gcgC8YGj3P|CFAp? za$qfH%<`EFb>|rkjk)U^7DVl z^Pk91{UU66Bh~b9irMq_<-NhyStc9Y_cNh=eQx%{1_$~Rle(m+z8(vT7x&Rl=RGMfHS5H7~QC$yH}LP>(*Nd7PH@3_5+hhpmaWujaUA#-AVS z3s(w_$6p$)GY9@+{Qk{pow@J_dulcHjKFbrX}-Oq%N|Z=#e$vj(S{rdj2Uwk0%Me& z&H9zk#a}#;XqraYw3pmjsZ z$6-V&zVSstHt{??VewQRgKG~ezw({@)hZnNW{T~~D4GfC+skh5YAvVZWsMWw9(gvS z_WQXfnr@73)rC4|DX143cb09}Na^r9zI!Th#~7@w!%H(O8pSFmgJKnaxznNjc-?%` z>q0tHRa~5%>M*LA&&1%na$Uf^GAw_`>ZP(q`!Z;bqK_6sEC^SPiAak7492^x;`N&Q zc~AaM<~2&u9jPgEF?|23@I9Ta<9>d1UTlv)e>E4jr_#|i&M)1o@@>v5tiiVD6^>AK zPlV@Gg(VZ_wXiVk31ZJ{cnl-Qcr|t-^~Xuw^5SvvG5vew%FEChEJoV9Xw*JC|x47E^VBx1C`)y3*LQIncFD_H0^osR!w6 zK14lc4{{UdE{sQ9nta(Dh?`2jEcQl75$!_Ug_Ydt1dKkfFy&&5WZ!`S z)Ed==th2D@+`z1VTxmsc>E7b0)H464pw!M|(GytcMykC7x+4CXqX+i8Gk)?`I?vTz zzUHdy)sQ((f60ZWsc0}EG}XHVXy;K*U+%^h8Y+3TFrv?Is?P3-X8U7x<(M-ubJ?q~ z)_9!R39?^Dv0s-$=^~w}YAG!ayjNtnnr=ih0v*}Fd>9Kt5CC)epH&L_D7|j zYGntO=ZPTA#qPnIW*%$Le6897p-s<_JOHlm%Y%7+KbSDavRSQ)rngDU;KMZ4$+^&0 zR)sRQTK6f2A+(uJf|B@BkVU2pn1ZM9@lX~)ljhZcHK)gD4qO{+{m+6XngCn+EI346 zbl#PzlrehuYHX!cDR--!l8^@1Wg+kMaL&w6ztVmYCIOuK4Mg>)mSi|i5sVD9XoVd1#gU3(KS*^M5L+V z&4q}VobAsA5x%OyIlG!$J)_0q#i;1H(E^{A%O5dpKNYknCy;Z371p-0>b96w9;~wG zxE>piQ*g`F1IKwmW*ZH$uN*JMXSHkfSEb}KWubEM8OM^-M5v#Ep{j&Ms?|?Y zWrA)obg6e|-C`rEm&Nnd_oCy3#?yR{C|sMc?#x?Og>RQqW8r)`{`x>(pA585iT$uS z?&cVppPITN_orl5)%k^X)+wOYXTR;xIMC{2te(|=-OQYty=6RHX2waJ*F7Z+S}mSg zrl|9WRmQV*6-GfJy2fd?7E^e-02XzVL6e54;mV^M7%a}Shoz9a%zA>;GX1O;-|9q z%>z~3V9|27&MM>(chmY^i+yW7yrKHJoI&$Uw2OY$E>VwsJt*c3XWvd`McYm?mLc=t zjoEEC-s)(3zW7-%^Gt9BVqHWWuGCDH{MNuiE?;sxAMF~t0p&(rOLa^ zgR2-_u0$T&s~DRKI<+U8Joa+&gCJ-}zE;_H%I>Pv=*ePmol|ItJZKhWo9k5VF)k#! zO|LX!+)W;&gIe8M4BM`GF?vTl$`X7^vo&LO_S_gvm7SRfqcL&R5;59kYd#XY@l-gB zUV@+(#9%eL-b;o{Y)H#jQN}~NRJGMC%OB+T^Q+F^A9~~Lfn=fWRgv?r7yondy;!IZ z7LVkoJ^A^8JkFUk`kWnMwfifd^KE4X$G#h%ufsM?+v8)6vD>NVNXPA%C~|uov-eVZ zj%6@zs!Yy2XpXUurh?{rg%SKojy0HmCdi?dmNVb*erFyGPBp)?i&4L= zFh>=wJLBSwFznoU!jH>=vrnFyDqn6K zm&Br}vRCsUGsf?jiY5C@`bs>I8i{(Z6?c-i#WS&PT}M)l7WI!#Qnzs|_|v+=%L;?m z2~l6k$CmXYO?PI6)lbCit((Ey-KdJ;+)S7%|1}TZVpO}S;Ehj`lOi}Vg6JY_<3~C8 zy`C>%nvby$IdpVvqIL zjt#vZw58?09TC|>;luxvUMnQF`F{> z0cK`>;O2e6_nZBn^ZU?hdtZOYx7~#KM={YGm>@p?$YvLcY_GBfVwA>pGup5C39r;5 z5ooO470UIj1{dY|AoefaIL<`Z{iBL!_&SzW$KaoGE;$+XT0Kd3M66}1X3RS_yTCH~ z?D<4;ogz(jjH=AUb+H1PQC*)|!!g>QD~rRO0DC6yMl+(AAFt;6zS=9=`_QN|F);cS z!1Oxz`bj(atp0Mm>>Y`!g{_#JjDIg7(qpWbb+|G#?Z})sU6QjXrjuz{NBRe`V*h@H zRPF89w06nFg?GW4>QMZTW$>=*fLhNX)Q%sw7Qa@{J`${bl4pZ(YDF((e*j6ErP~k5 zIpafRj=@ zY}S%aqXQE$pZUJLH)7Ce7Md+)>o{fpMBH3*B9zm`S;u6Uj74aSve1tYZFZqOtOSHQ z3sEaEt&(La+7p&2_yirAxp*XKfd|PrI+K6e2V7D2qdX7fx;h!NC?5)v-&I(?_2<<# zlJy;-fV*wj4H13{~zxrsq6RztZxXC31EVN~yUb2j+7W?wVQx)d~?YF#00Kkv)0 zGeYZ8+}yrvs@(rP92paFni@iX5(^UTNZF6?=3Q>q1D%n!S)_rGa=9=Dzf(inp2QuA zQ4$NVo+zde)mf{qrTF;(z8wnRk>g<6kG?gO&cV zl9)R*H3a@5_&XN_eyrH;-Qr)BElD;F`Uu>oH80qh_3rDRs`GRyh_o!3;Y=9gwZ)*%W->HB8537oH;+CU1P`m#kGAqb{=s2H zA~b6rBzz|b0V|*6JNn~Zg$JS|T5Ec9@la|iAIS6Sf9V_D&)e;U44jy{iPf=1jb7ZA zs5t9A^vQPdO%o^MPvCK6xriQ$&YF7gM4oX2q{!sF-VWqGeCeg4#iJ9bKc2 z1M*>BRk%_n`Mr1E%jbxUn9sBeW459lGO&I6BV$}dE+sOi5`80^rQQkhq2NLDGu48E zDf~xLGK6JG`(6@#{=wr@u>>_rM@#^H(SKHWFK=^#+sUOjWsG98>CYvs=rVkg7;KebWql{>nVd-NL2U7!F3ak@c<>jJjdeJ${>o45 z*2u1t4aP-*VpiSS)+8>$`Jax>mkE>w)yE_)(t!Jn8!125ah` zbdiZ!JzaZ#dTYx3k=?4lMSl(%7vYJy53wkUQK(mO2=_I_=IiFsN7usYe`QuK>LQ&Rd&Ay4*Jvnr*v9_3@NfosIXc`x-Nr|Qyf3FlYp#oC_hE{CV zEBxkHVcXeD7SFsX-1JD;j4mrT-`{8ErGTh%E+c_vDR;JS>=$Z6F3P)#Wnx%A70d9c(octT52#ecHv3j0@^r*&M^r`WdNX)0 z*mZBkdr66eZD1U-(qi&EHiIFvBZqKJIWhk`RsKQ97G8y(O>)gk!H#MI&&B7Vhq(3v z#*QN+*~L9|w(t!q0UelbihcLI>R`N`ih!-f(C4@rWSA|sGuRfxt}MkCi?MM_!v~u4 zr^?>?O)M*|mHDpnddR)BM{df`JMuMSg1zHdb`{%0%(HeYIcBHpLKoMuk`19l*rJ@A zfICs0N2h>>r&Zn<{lxH3Ohc|KX^IZI?av4)8zJSy`|m`Z$WaDD)FRU836+`f0#=o? zuU?8>^-3%#?XF|HW0z89_LX(zL9aVb>cN!Y%iAtqhMi@z8Nw;$#Psh(bulahF;qgr z86beDB;JMkBt+}|M^gIk<5oU-{b2m5sN6rv*}Y`S?aM!>X5SaR?gx3CPFhsvsC_u( zRh!n%IGp60c`i$>oTxwNm4`pUQcy)tWRS#}Mlgp}hmp;1mC1V*+MJ)y->9N-JzBNMT2Dehr){lUE-MCOoT4Y< z3_*%ntR)~NMq?}=DfRe1R@zPRHn6--Dx47M)Ea_q;}6TrjN9`z!y<+d^|FT`q?}0q zPE_=FiU_e&FWi|GFU4ll{uo$rM}nAh`A+SCX3^Y~E}|#mD;#w zZ!2!@MeUlKWuu{0H9J+tX(<}OR5AnVxZ$^Yhd;35RD$N;w-Xm+tjE~fo5lsaFoaLa z$q|SE_K0=Z|tS1$HKr zDPaDEMLMa^JQeSQ|NXzs2*{r$GadouME(`UL$%>eG6nT1bnDYz$@}7Gyj=XJMAX|= zW2$#?BD0<-N3<~|F18_$f7>{voT&fKWTO6il4bT|2Y&F}?Qb(~oZUlS0F_SV)V~-L z?N)wNf1l-ULGgT@%QTpX8nQ#-7d_?Jbv^UXtkF26MJ=^L27T;%x%Ry*y;eVr5rkLE`F6~?#Ux*dn|8*MYUZ$ zX73i%xnJip)UJwQBw`{|)1Syc*8Y)r4weDAFWhihX=BzunhZ!X?9b)7ORv)8D?ta* zmLnPIlRRT7^(g1^Pjgy$4a@wun2hPm#y;Q+#HB}AIec?lA_L{vUCz%(aUJ64ms8Du zH>zXRD%QDPoX{UeIftqjJ)6bP2Ll)C%co_Y5^!NQPiTiL-xDb(PJee)E&nE?FHO$) zQC2z`kq5#bF9iv%TkLcBi|c$r4VZRNUdJY=(Dm!mbIUeZZ@0zXDMt@8RvMatsn?aF z2~6dbfHo4T+_W=fQ3fu>s>6oU8tJBQgcV13v((;E2^?kF|J#LPM(sW&+HQ2w zpraq1H9*EY={pM&oCk#`v?pC?(ABgGy36lDYpXxLoqF50F-RHU)>NRTG-r`oL zwykH-C=P#;XKW{OsMRb{YeQ=qf*kzvGQ1k?^Dz`To7ET4pWln7u&nfHPL$;*jr+JB zXxMP;l!Uv2rTL_Qk8npk#c0y2*lCj(`@cjd_#h|K)az-$U97^?L755&&mY^H6rw6-Cu;IE4>MZw@}jNh-LgrjKdvcN3&%b(E{ zu+mhTzm@e)-rA=teHq*JvG^`0@;j*E_vUk!Rpf?v&g)vXTlkc~7cwFi9IsfY}Ff*`>D*fyN|0R$bp@y`1V7v^P=+o zQ={jB-~{}9n$aV7p!qK+dd7AC%Yhzdw5`?}`2m*|$I$2LqO#z$s*{c$WRG&n0B3Y{ zXXm(+GQN^$QD=?4$Cyj`;&cuF8RYo*zlZN@+uAZ~-r^_sqoVumahiL5=o9YZ3pbY^ zt61qy)LgnoYR+aD^Ngz|$bp?PeE>HZgBij+^vFD}`UQd=d>=a<%3tGQRQy-b5L|xS zPckZ4`>%qOzt#RituBwjOUG5796fii3;$OA=6hy5MkSGXW^aVazP!59pWTc=v#--2 za9j;T4g@lz(B3vxzp0Htx>5a0P_dM?PM;~N@6Zr_SUhZaJz-pOqT^pAM)$QuAePk# zR;zGaX%ebwoD0%EN}kMZL1#>^dYg$Hi`WS_ti{l0)*h$1fiyl!xXnEuMTMNA z&-e&Z%xYg}A(>r-|70@?SzJ>^&m2G6CgvF*KT3_A?TR0LtU6iI9UI%Y3p;cqp>B_= zz4zk3(MS8e{7g^nbMd*XZ^Kf4BkHf!LoN?HToW-@@a4-oWw#$6{Yj0X?TY>k$52;K z2Ca2H6fBX=dRgIaMwXtiT$&CyJ_?i?S=$u_sw1oX+y*z_IkUm3>)o2V>2YSQ_ODKd z+s4O}QX_D?;z@2rV;{B=IOjENmsT=e}(!ga=dvd)!qrTrzpm7h47QcofG#|(cO z?Y<*!hoAeGD2{JPo(w3ls_o%yW8;KBmw1%etfqz%Q@88qLoOHJ33}+AdM23h&v&rX zQvCHjW2W76#NqdPd;Zv3ADjPU*^3}YdDQ< z6|=|p!@?A8E5+tvl|@6}YxUy$`06tzt{)Tk67fS!u30=LY*tg_ho=36_Di2oEUL?q zEHSHA&OgYLg{CaQ+OvrN7>g-ABBsa^b$|P{^rU_zjBzd=2PbBqjl{(4Z*LA0Dg5p9 zn252(O7kK#B1nDdn|b|$RJ}Lkg`aJszg0HThn~3(;QxURhD(c4(}E8hE02v!CJb_V#nPFKzi0{Iv|r zDup(c9xqer{_p!4*p4R>uj6c{SASYmoaKBjj~qu?RWqBAmsbWlv|3|)reI99dc5CZ zvznUU;UndxV1iR-539Zpk1DT&lc2}?9d-N5$5L1|oO5W6xt5Di4y{&bl!%Ne`W+xc z^<1rCqW2IPf@r$*X`Qj+R%ZRDDcD$GC52Cto<*kUlNeU8sW`8EMv6t{LiRxUk#dld z!W&7Clqq^6KMHf~$-iGDyLP$wNjL_L_m;#6UsrKK>SV`oi*H@k?XEexUS}!$t(&b( zzcn29>ky=IK9EBkdu&ZpdgM$!y1p7AeRZ#Ok;FM(Vi@6jKAe0lI57ooOuQtf`&GP0 zZ?g(9cxhQERLGu+0<3k>zsqkhik?oc5k)-uwNSGxnrUX{58PN)cckc>ojeeKb?tgZ0}5(RlL5%o`ELA{V?k%e+v*;9;iCRh3EJ&cIQ za@B>{VVduCRJ(c{FK}KEU9_Gq_9c4rM1FoCKka+3a9?b|ALQ{9d3{bV;+-7JJqUdc z?M#>E+6;}bK9-no=3TGboO|E+iLKx}2^23kR`^p`x1wzw-;t9a(BbSWJZcFVF>}xu zqjrKrC02y!3bhlqev`F(A(|M^<~d9G`9M}P%GiOo&cBksfHFNZi2P%6D(kog@i|aP zU*0>S`owU5Ik@V=NqFsaU6m4DHr7z>%wZw?Uizbp*@gDKX`}0+Vms|TN)HuSupisa zD5DRZ@opDh!fUAODnrIlzsZn6e`*_REXrc=&<|xcyD6Z|w-Y}K_h{cCV;;w7C~;^D z&W^mOs*Q>Dyp_MfZJd91EYH#ShGuo@i1dKeE_nTLI9r{jI5>rGdRC`(lOL0{1M<@% z)n-*HN}q`zL}nZQ(2-b+FNMX9wV@y{am5&SYe(&*{fZc`Za@IAIIxbHUfxNNXPMm`bG8U#Z$f$YbtR*?5%$ z@ycv;pZ|t%kF(3b=WRLNDkgh)HHY1h7yz1N92a)kcWy?hEJe$&0CzVQL+!<}QQtgR zjZuC}uov4XjKk_PK@nKSD)iTSU(Fqi-VvP~Jp?P0P6((U{+Kg<-pQSIHoAFQY4AfA zj`IAinBE{$#?ON*PP!?X-3L`3>ld{(KLkg2g(nP0Zv;c1DyAz9N!z1V*qK6O(G%nQ z#B1g@tB@L00($I($v{w&JeBl*tmkH$tt5cZUIG$4+v@mumR%;&=5LMPYL!+4JB zzo8yIXlIp-(){s*BlqyGAlrGJFrQ=UBTo z&X`D4dPGe{|HFqml`j8S43^2XC;31R1qHv$dLvr`jSlM#h484t8C7_F>x$~gU=OUv zm+E6L7dInWwS;ci!bnnJeMY8%dW_Rt7j?9k+ydxIG(70;wl2Va#XP9;dkqw*wO?6t$DzXC=eyUw|BN~c@Md00*DLZUH1l^ z53mHh{aX3)L`>lj^5s_d8TAnq##mlY=bl87Vt76`a#BS{%`P0GqwR{1W1KujM~m@D z;#tRL724ZMK*5jVZ|qgO$jvJRe30*Cj$(zmv!K2Zg!tTHctPb-E;^KFxaXsTS#};u zcSsK_0aaLKq0eknsEV;#x)`ZxSq?>&jZ+q?Vm_hLP*rCGdR^^_wS{JlZtzp}GyXqW z21}`DeJNVOeewPEXEJx(vxyq%iRbqGv+9w{3Smw~AOi@kn=Ym|D^JTQ4ftN1w{Y;M zpM@_*gy}cA0w$zJg&CuNeFKw*lnVxfF ze8(y84)dPS-v8!3LGAGC-xE^A8q)6xF(ak==lq`@ID8oD3q;dYbDku`|x(dGLF^Cgx3LH_%V;m5gB41Psb+)uVHL8Q=Go zhgj5(@8Dj%-Iz~ewPkK`?l`}>i#OejQhB|`t-_)bH2^`RPwVpAAr{ZNnnf^9f132u_2-7-erY3eDyWt&AA_?MCegT_dHkfK$Xe z(jzZMHCTnbm_0TJ@_rBm5I+Z5?<%x_VKS${+xOy!(v1pl6mO5JGyGJpxFu|5*VKJj z^>M+icE!;sBP>VeJ>A#2j$9Uvs~q)4o4;SEk4skaZPAbT-{mKh@y{!=`k6m7+fGm_Qk|b(Wd4l-&d6 z414!i(b%3>qxrdPec85-f1jzxb1k@y>Cd?tuDyQTQZ-ke+7wf#xC*z|#kDU573YEl z@OAR1_RM2yJ%UQLSN~`s_o+Ppu~@E_g@ZKuwAG1r|OT!S)*Ze z`LCba`@CJLKtq_d>F=fSK8MyzG-oq3{-V|G<)JIC>b^XDxh|`www?=1X{Q5}R~VA) zZnbCkt4JnXWF3UmvxK{p|L`YOSyisZVl~UR-qY0-S1e%qjuVIF*<}6MYpN})9gK_} z@i1XbUTVpl3&T zC9T>!uFIm{7X+RO4iB)YRY>?cr*t?^d&qjw9{*=)rcAB9#)S2V`$3YNtX zqlR{k)SS(5b}Tcu=}uIo(JCayFe|K8weBm4TT-hU zYnSK@8Hr{k!(-ZkUDY48p?wRQnUX=Nz0wY*2jA`;!lZwd*wBBKQBmMj*TOdNM;*_u_auKb#va-XrmyeJMXI3h z$royr?KER-UL7m^`K&`yJzK(`U13}{<_uIw(4wlL-D{n3thWz zM#J$yEJGt1)>n-VYj|W}WO#?cyyzI;|0yL~#Pv4Fi4M*QPKAz`nEAT3*hYuVF0{f| zSyh{43*V~3wnFPC3I#(@qxqkbn?_D2QTBcDd&pJ8?-|~4FgH@-_U_y~5+C>L!bx~{ z?7FIH84ghiv2<9!Hr7~MEDyS35Kyzv6~W6qh{i{pzEg@TXILJ9zy#> z^KdGy?e~2&jIMF67hB|zq(fI+MoK^SaxUsY`r^rEI22Et^p=!0(VJh%7e0}COmhW(%K!vsqaVf2=QvoKckk=A$3NiMi|`gU@_)05Sb#*Z1@iEnnMsdm3|s+MCzHu zs)OUBq3^+0iV#ja1yTIw_uk!;C^4~K{MO~+YQ^oUp<*yJyCNqPa4b3cer{-za#cD1iFA^1!h!!3YC@qKU z?n$;mjGElGV$DKJsY7aaiI7#*h2Q3EhAJg@l4f5pT6(Ut{E*OnDgkx$mgiJskfR+V zeijeykzj)UFl0E5^Tp`GMn)7PEd^IMs%&N-=Ra228z1G>$eCK-HT8x(L+gOM$1-N7 z@QYCi#8DFRDU&u$G$eLKhx0ItFRuUtFD_@J1$pO`&|b}bWe1W ziz=%F#@rX2zZ7fsrNmwp@6-!X53klO82eatpV*OJ2la7}Dw~&6XW>hB54!OC&kx79 zZ%d7XDo8g)PoSGpy#n`(h`l+4uiLW2$3&Lf;}~OUg~4q>YRouY+~*Ll9^>_Po59-T zq=9q@W3=#2xNa4W+g+{I0=gr1yrkZsOnKY z^w;VqY~WAT-|8NwcJ%+$6K_of`|lw9`Lz+^*0nNO+&XBFV@OM5sZKc#sH@)Y$Jj_< z+~+X_mocohImTO!OPzzSt?J2_hC$UzEssAAb8652OPCV7xi9B2*8@>{*#}ZbD)a=I zAxO3rHzSZ!-%>K;SOukv8Eu9`nQ`o#+BWBE1Y!?S<8>lm|B^NDs%BVgCsnslV)BYa z_|I~T@$+8G<0wCNUJZ{pg_Xy(+SCwi{-0B3&EKO>6Eks)`dG%cSclJqVY{`CVXbFf zF8&Xh4f~B>JH%_=l8n%I@;9eXsSf<4@`;^_?9X8chU;vMy&Cg5=VoK;ZyKXvb=l6% zooT3Uq`0=x#xrZoz3t1a(~epm3ZB|A5XC3e=BI*$x~2=7U3?KVJB-vvQ)NoWs*gbz zC`CUWsMaN1%DB|C*T?tq)feObwKF!k&wQSSCbJrbV^hzsPRYA=B6f%)`(o6eX=v76s{8{$WKM);?4jtVCbl%Gy8+LK)&a z3b5@0O}tZ;iyf_aedWC-*$*(iUT>POj?;Vvt51SU&3~ptIdvE6XAjRT%Ih=FEbaPM z+)re8$EbAisJB^74eRVZV1az1y$Xxe$$}6=qj|!dG~7JhzK(m{?fZJV`H&N@@L=E1 z9iGPUGwa`YevH+e9+k{$3aET3JZMNX9`n)3UIdSVSKqhAul!Z`@wK41nGF*>U_Cgg?i&m+HLT zc{lKD>+{yvvm2zyGfcl5OeeQ6#cseUJld@-yc4i{(7T+jaoG17U)t_n!5A;Z5AA)$ zxGr{tF3rmJrZHnQ=P|^${;IO5(|FZ7R(Pk5x2*lyg+8ZMo^*^2ux>_uJZZmfQ?nLO zwLlcz$^Gm>n7FPz(Rq>1toY16^Y!Ik|Jv|p(O%uQGW%3?%{DX^k70QT4yoNoH?q4w z#*Wsp!k_)RRbP)O`Li2}L*7~F+I2JPgTtrtSsaQl`%xH>coIxT$6~XsIf)1Ksm*Lw zr&g7LOzq9=XK1*HO|D9ssAy8xNX^*{MUZ9H zg2u53N}Kfyf^2r7d%cRuHi;lsEhzXytVsAv1q5i}uGqGgq(OD5ov{M}*2U*UbZ zi_eYTIC@U?a`E$@Hms_@kK~o#$t$)q3B!9!8w0l2YW5z{zjCm2uLvv|F3ZGH%%@cX zmSDA$$_@lIs3O|eMl;MUdk>}pSAKQ9+DozfzyR4qj+dx!*7M?s_|Z$i@8>&)wft+t@4das z-3rB~o6+LpeY(QaL>Ka*WjGH_6)mdoD_;?hAgk?tg*A;XaOPnXVN0o!QZMR#PkqCU z1b;ph{zFr7afHXxndU(?2Vw`86|&7{O^Zz`ElcPR8XwQ-;<4}^)pb=$_Dc~T$cN_` z`(V4+4?M?nr@r?(&dgGMBnVW^1r3Jh_;r@9Qmn6M=vRpTEH!H1N==&8WdBy%Pr|D^ z#K2Tj$8<<*kJH3R$cE~|nX?AeUcKJFj>f<#dKlzGY>Za3eTc=1_N$~FE`F51;Blhg zP%llV19AsmiDe8X(Kz>oueHX+=g2TF_hlq{vr;R{85h{moQ}>pb^b`>a2U^UbL@fL z+dSkkJ}JH=V~tgN^7y1Nqi!F@9|_vPmTI1=?Qohg9xkp`#e(XG6AB|yL*W(m3 z-*zF%vS_+{VK&*nYlMHVh=JV@&mVp?z9svmTr9@q=4>Ap>wf4nK_F)(>N!u?y{A=_ zpU&k(NxD4Hz9{q&JdRIMmN)@1W*6OzT^rYPq02%}g)=|9Bn8&e=fAKU__GZ86Wy45 zD9THC^`z2dnS+a#v*PI|($%R_>p9^z*VC2EbLu_Ncd+a(ukc0W9$VJ0#=ej%=>g`h zr<2L!qGBJ^*T;0e*bL_G${rA237f#2VR)>qnHO`+a>iU7=GZ}}hy9n*qv)ylt$&m6 zj~4$^u=+^89whW+VcvNcsK<1S(^Bccd3S-~dhqARyzBzhlhWm#2o050S|_S?nU2%3 z3yvH7jV|T*U#mVD<$YyS90=EA1Jo@FyyGuxcnw?GreXQ^b(fwM-u>IW?eyCj`RXtG zzO5lYm7bgz`7zegHrU)`o;y6E6mzyQr_uR%blBBL(UIF0IFFHmaVFQ2DM-!*kCl{> zH1lycAE#1)^P)0F!a6auEI)eyvj<>t zGW*{20BoO0q5j2abnCS3b_O)NP0Xm>HpVkyqcEean^B((=%(UU=RfV!jo*xtejxma zHm|uLsOEUqbcE2J3ue`~Pp|RWGVEQ~Bgy`?;rp`ApPq9<3{UnwZyY+^IU2;VQlFz? zV`|OpFqM9@ShdXMTap_M8mUy^Ts7x!EAsS|&8`Xt`ovJza40&MkE_0zgrmQcvB=e= z_Zo5R-{gy0B94dLH*UY@?NtT^+OUw)Y6*6SG@GtD!5x zkMPf%5c@lKo6aP$-1*j1gCQ!Rrw#Lrs~9M^A1e)p~&IiF6u;HOm$qiz>spW8v5n z%k%9ad3n;-w=wV7h)#Ya#-M2x62~fN)`&&tJ7ulP!w!v#9gW1i2u)eRiZ;uAusje1UUCwdD)5>(j@Wo~zi&m*VF$ z(n%o}a6Z19ncAsQuD6EymtQVYzppCG z`=flv;>NNzG+RazdjNma?)`8&aTtgCPx3e0K}xAOnlWxjwC|hJhw0Txwodt~R7_XV zRT#fsZg;wqVYO_v>0S{XTup6?Q4}}hxe_y;23BIC+ht+}9m{1Kx*k!ptxK1j9kI!V zW!%iRu4C3NTbFLO)4+C2-`z5?y(icvr{DF1I}xP`yVXw5Q4jV~o~Kb7dN%4wI_|8- za_Zz~tJN@N-#2BolEXC>yy{#-*$HJL*0LD>CU^VApPr<4vBH+U6c3cY5e-5`qN@c; z6WS78E$V&8uP=%^Bh?UU-#3R;%Xci_!@Lt!|5H9vUkVDHK4dztsz-`eL#NZ0jA`j7 zVM-ExDc)bHN3&A&xkrKY?7wN)$Z_WsmW||Jg;A+|v(xW5u|WGoX{`&f+DC$P>hg%z zpz$uHN`v$7RPVLid}?N~w2AT1wTkDeeXVzZ^G6Qmc#rILAuFv*XEJ`vc^Y)r>!N9b zMyu!@p2=@f6nX?r$Eu!gMpYBpGm87vj?GGzv*EjxEbSsO6`r1Mj#U%IPlQD+hYA&Y z&Y`OF)91;pc2;Z}JjUcVvGz27N9{b#!&QY6g zci#~GhO>YyisG+O>xsb1MHA9|-!tiR=CX>Y8;9pWrQ+|b;v_nB(ADs*TzMpaH%-{$ zI~OtvIuhCt`tMN<=CaEdRkEbo z?>>38SM57kI+|kgXIF7#jF+$u;r%$$?>R{Q_k~!moUp;EI9gfrNicF=S%L5*-0RoZ z{9K)NHT)Fzbj)TRU(6cal*bpd4)WtAU6djh`;3WATpwPD3i|#Zc|4ktXH{r)*mD-9 z;~S!ss2;G?E$P?yq54UmZ62VWtImlzK1Qz3as*$uMNcUQUprCiPJVo)tI*DcuQ5@B zP2#JmsDLO{AyhFji*GYXG7nN!n0l|wupQLq815v>$_?q5GGhtJ-#k#n|v|PRtQ$E5$CvQce?T%Y~H~TfQ``&@)-REOIlc zh2noA)YMr#T|6I&le|{ntmxIPzPn-xr|Y`PXkp8IoqA>#y2})EGaRaq$EZN-=F~^g zdm#Rj#k(HKPw&LydnNh;b%e?we^h9BE5DmuqhutigJOx}V*bA4f5k zcy7jtw?eygi11qNx~j>ULo=CmW!q?D>y7eZF9tuWSSse)9M~i83LNTbSK3eYXR+Tj z()>VB2IhX3FTVG$(andh_!Zsv6pM1O*mvf6QMfA%Xn9X5?8Up%{Z_kCg&1qy%I{)A zf2N_aS0QpNLl0%cW;Cm=)EgFwd)3d|sy`2n{+8gF7&6sHuc}Dd%`5ig41!Df2g?6g ze9==W$%kpx8?kA^j8hIuyHFRNf7eyUabs(L3|V@b>ol+$!+@U`R$=Ckl9{C^U}@gh zj8&KW?cx;iwm=u^O2KNX__v`y{Jw_rYK(@~jn&O&KKou~lMD5CI1mr=rkoaeM;LQY z^uaIW_fL|agKbEUC4Hli1PCsgAnE0|fabX&aI6NA@9VnXu|IH}tMp>%( zxZyS*m&K@a-CVZWjAFR@A7T%_6Q7M3!hw9XBX5qk_43(VvzI~ zj#0C7^P<+5$Emw{nU1w+yg5FemNM&}Oiou{j#M(M zXA)H^iO>6;QTj2EKbw?ZoL0NtU&M4b-wglIYd@?e1yOJ+JMNYc> zOdB!$S@mNm8+SULx!4CS(^5|nTuO|r-mQy#kb|m&2xko{4=ts3>_cS(f(*aLhnU)r zGR9+hRAbuMhjb>gTr;arJrN&^UL|#2^ScbuQN`~Yb|&M{3-_I1jxl}Qg)36?<+aRO zrf>1`bGOxNoH#cBMR7(Bd+I%bG4t#SZni_M*BHKDw_o+iSo7`0{}e2vepnQM`UcSV zMi8#J?t5NDeY}+XIU{k?Nc?L;4Bm_CGP7=tx3fie#W$G_ANx#-9!bY9{6FG>M^zVi z?SF|LNk4gd#6RxIgFd!r?7>y}c8#2V<~_+}Vr8e}KpQbN1KPOL!J&^4J-ypM)8V-= z-%G)suh#UlMg8$pVi5n4Q#4|7i`sr@(>@DXDqXAF`Lgk->KZ4!2D`3mzJsAPNp8j3 zh-2djHe&dF_2V}iR~4twC$=in<+^Ok)!5?H!SgG|>xZp;*5!;YwXeqbZ&+j0@7O*u z23I;(N<{gyn*x^n3}`aKnx`9RY{B}*(v^}5T(u`rRy2m^a_*@*;y1>6CC|H*j56)E z;`a|L3y*iJZatw-D>vI|9PfI2KG^C_!CCpR6~i^FcxtRV(?HHIRKc64Mm8sX%+XRcPSK6laghoio8g_YjSAbBwL927 z*{e&a)++^FsiF{|D<(5J-WJpm$9Y(rMAtLH0I|GP7|?#^L>qn=#1KR9BLlw+(uf=A zqi^MBs(74QQtyn8dTAZ}$d0aiT;a$;-CHB#@vXc*Ct~xOkLCYUsk2RsJiNG=I;=K= zZTB}TEyRpnew5nlkYXtE4yzlaQjuS3zL0k-nADr=RQPJF*Mp( zW4*qZ9H0JZWOhT*7<28q8TGMD{nH2Nk`C$)#kVs{ll&NX69t919cT2c=Gjm3T%ru^ z=lpbq=XYY&!gLR+&SrMf2w6EG-PygId4S!k)-C%1Ic{n{e_06XRl~U*l_i!N$7vAVs8Mc(C{Po_~s$}PTETdaj>ZQEqKjrICa0!FKdH8sI=Mm-s>sk#i zb`}xBx^@$`CfaCm_UVkedM>DOL5e;qI#&4e>CaR#K6?qMYiF7mnvAK&;z@l*A_`<~ zV~x(}$d?z%iiV~6KV5XqMof(q8+ST-Wmgp(o(;^TeV?g;<7bo(dh=1`Lr%4NWn<9f zUmN};)^SR_n%7r3XuqmiN1N6m`_4S4m8e<2DNg25e8*Ve{W#0bFl0@4v({#N5t)Cb zXW{7CaGa@XClJ@YC%?}Z)}_V)&?Qa;op!R7*@||`$k_NmI<#T|&gT=mPVI())EsAw z8A8AiWW|nM0=j&aUlo1R_*Bh*Ck6iiGD9$Zt<{snlk=ZZ-#6; zp?zTQT9ofxMu%G!zvZy#Z1ZleCdkL#msS2kikO1!4f&8fT($W;kj$s(TL+HS>!??S zl>9dQV4s1*99@rI@QTzIew4BNal&h$&9Y8Yo%e$4+6z+pz;UY4P*#trohiXuzb;k> znRaiL>p}fXu?7570)5O5!M?xSkb`;ejk=U+`@WUccEZ)qnkY&)Anw?1|i^ z2ePN`d;95qsbTv;9xqQb!*5Q}W!Se!!t21+HN7d|Fy%S*MBAAOW|zd}^3Hok6SF_a zJ+9}?j@>DCWX;@{z2eo%eFEL0{+i)cF>JJtW21$eXb+V!8l+ z?t93dARLdROWW-78Q?R`#>D=$3I(fOcpyxa#GUnS8S*dtI6=U7M$|JH_;u{@iz`X8yW6x2fA6(ppU_ zr~BAOnnPu~p5}OHcF1fm4YAUi`4gcWq%OZ`d;Br-f~T@4>0CpfR~fq!m6-MOZa!XR zgJ^D*_60hs&X2=BKtUy*qxeP%r{en$(Ndh3l+q{4m!CCT7uRK75FMEgmYM5zV7beh zPl;9E8_9=T&8v*tW82zCT2{60Lopg$7e6;=Gd@R>yzuE@i@9zGwl1njIX##)`|(^N z#G0W@9%Np1(8pc)ezq}TyRmlmVt0<&^V;Ls%1cw%qu9E$C<$AsDoiauApB_!%{#ag z)gx*eHt1MvSzeNVigMk`9s3GC0*B~u=_7~6k~5Myck;`tUjO6{?If*&)e-aH*k(Ef zhV--Y@CxhIuP@~^g69<-=O$X@q?XeSR~qXDStbbXOL+_REOT0RNnb{jy}@*vYdbI zIF!O{oZS-BCAE!qTWKk6)ZM6_Vfp<()@ND^H7AljkIEV{)Tmz7ED}ALr{06MUi~^( z&aqd$l^yBb0(<@SpWKiJvH3WDGx$zhEt3=9pGUP!YJB6X`nL3D>gnd(veQ3f5>q_& z%VnBk1Ej5v$+<_w*l=ZNRAcJobLEcjvZEs0y30IMP?Ua{@amaoC<^q_qQ}TwkLPxiZQnuC*3#tML1JQ!vpwQh>yihC&oWo( z{U|Yx)YbI4^~# ztA3znJd~}QTjMCJMo@7!oh;Gm)G;;lB@QGqLT6&DizoVNr$oLLZ(Ppx-Fdh2gj4PYF;y5tb_1JfXzwn;LiX`G=5(`j z*)>mO*Q9pJ5bW}|>vbM)M3HBIS6h`K79;shg$Jd@#wFc$F6s@9SuFo=yr2f4- zdbK?}N!n`9oIA>drKKN&c#%EQ-8k+OAHm;wB+=03NhEfbP|g$7##dR*XQ<7c`kJ+&_*iLcLv!v^ zpGR$IntiISzm`!|)&0(9OKMhu%p2@hfl^n3=G>#ER0-O)Wa_6)j5$*+7uM%`D$By( zp2$$@n#sKQ=Dvq=0?Noe3E_KPJ=OH^JJ(Vvi>~5OQ&h{(*VMD&wgY49Pi)GCvL~WZ zSZ?=Gtu7l(BYQo2PA3mi>oBLlo{uF5`LsI4>626$QGrYcu&&CcZl3hD`%}^7 zsZl(u>XjJjuo~}39(z^2M!Ujs3<~{g$8+j!IST=H41H>w;ndxzxojqCe<$%N5izXy z(^YPKpQ>Wz|EXjSUN`b!+PXsRX9$OOgCqHTewY2?P`=X*kUEBXOb*nOgU4>7I|H2z z&gFOd3?5gHzFYiDzMGoj<9SH8)Eu#UIC*bGCvdAD`_ zENb^%H>drIOX;Aecj?9gfAHeZlNJ57?pFu>EYE>~KgfxTM7j^8?pM!*^REb_BcDdA zRw`#QTt8RFSNnA_WqAHwS2aE8Az5*EuFe?VtvuFLIEtyhS+{0wr7F^!a~z7K7@cC> ztU^foM!IBkUMWliYQW85Rq66kGQ*6SK%OGWtXn#2P-$m9bky=y9^+^J_Kp1YUBz#p zlIPMTcPWq8)tzq!VZmuS@$2|Rc7!weH)pp~%`_H!hUM{EQ9kU&uww}nbGXWYHjVKX z)>(md+f>gmwHcObnfkckz4wcwUwt)hmYnH~u0Kps_#{*`?($1eJ9H5NJ1oFN12 zzHW^9Lh8?#wa4nnWfc6>K`@X^n{vj%-;@LkjMNd_s*8?gm@euks;!U2`u+w$nhuA)kz%mwWs-E<$0?1TDL2&kNb#e+>^B&Q{A)~WZkR!ZiMWiyvX`0sofZ} zYxT7oZHA%yRDvqwNBQ6gDpiS#D`pM_FOMtEIT&RRYE-{#bk}##q9iw~*9YZb9zDoq zTcFT>(U^(yrf+e!ea5|N=Rnl9rc{BA?s)&B%Bp-LR~%OyilzEMep25N-bJld8x|z#?)A@#XW?P1aW{T7 zpHs&@t+0&!%e9(MfWq{oL*3Qf9G(ZOVfUgGVJE}s#5~Xc%<}PZ-%wM|rLz%HwvBbXIz<9i(I{{Ts0l(3%{AUdRsfT2Af-vFsTr$JpH{RG;KG z>~2mLx|s7A#7ph6l{c{?biJ-|srlkV@)#Vh(&feH!c|O6wgel!uI*lkmJ5>bWM9j_ zBjGMoqu=BaEO#&mi~HwtmEzIPHu81Y$V54@b;`AoW8$#ag~WPR-Ey&t->@8syBO!q zS$f;dZYZ*4V=6{7zCKJn6QrC}Xu&e|@5(He(BWuWW3^ zSfr(3i|FIoj3c=NUH`TjN9p>E#;o^sI;5$Oezg|rZA_f@x^U#{dixa@9ak*06gy8f zNXu45nS`T=)$6$_%f(ai#V&-`s7OTTB(vt7JO|ywA33a9*7cQo#A3O)d8N@3B{6OG z3)w$Iv8P#w>{qdpS1TaB_QvEWwK3dO@Is$f*Q$2vqxR9+jjE~a8mT#( zp?czu7O{Xp(qw8iPl%B!`E{0GbKkVX%M7ZzsZ)oGT1}QkCVS zYaCyOKkqiCY|Y(}U4nd^`%zWc?QxoD2(6ATM7g;rHg}@t(lt_ZHsi5rBaT%W4MXA2 zYA80DY3S~kjm=~x89Di6mY-Q7Q)fM~rYjfdUS%ZI(9s0gl z^H{)GyT|fBIpxZc{`KKI-$ssG^)mw1hxPkjC|<0yL<-%+Mht&eLl9^)odN=hV*44T zGcS^}u35D+Dw}#zH!9QeVhnc;MP|Q({Ah$C7w(_6)-wRDKpr z+09Ko!N{5rr72|)_GbU%!$b9@L(O0GZTi{r>(Wxy0jXA&|cidUrre+B}#F(iXPf~8ylfu zwD7%M$27)SE+59tFm%UDP+;1<+^kAiEBaJ5B@PktcQ_UsSl#^MO1PdZC^5L{U9U#YbS+Zf{$1&Yzii z&G^i|=jFBC%5Ss#Kh|$!wD9NO51(#^L-C0X5W05VocgGiZNCk#%dZsou@bf*bKwlG zf~jIYuQpzrR#oWkcKJ)T=2+j#n=yNP*GSFT4E4Oo!%mk09hcR;Zr!yt3^&8j9baYR zZ4wK9=d&M$Yv_w>J&edOaXp5}g$5^jatq4;sbHobQr1=Rgz?{A<8FPN-*a=4 zS!5|}#$Cx03V;56acDCfio=+Fcio)&aMHsHTiU;bZk%{n*o)ey3@ea~Vs_T%SrPSK zxqe;VL1k&;vH5+=RCnx$+nfw{Te7BOYPH(vZ*ofLbME4$Av;LdIN{aXbyf2n3};2H z4N9eb>_+u5UbptUc+t%<^hvE^#!VvfQH8#GCqR^pOZnpL+@^kiCeP<@iZ#VBRS9&{ z<)j9!m7|}Z)?7BLjrvx^)-lO0?Dh~J-QktlMwUYbHt3EhCNY{-dz|L_4t?%j7;$q^ z8}$1163~GSnyRBvPPCQWQ^;SXZJ&&_(B!(uf-m}go&H%-{@@C4zsR$R0`x^uK8sYn zx02#!*WVFdkz*N7X)H&u7_&PKVJn+yXx}Q8uT0m#n$*f}cuN&V>(W4Y$|Jr`PQxU zRX(6Ux%Z3R_Q9g&1M?9`z82ndt%$cIdGLm z(~pFC{F8SyKiTSM>#SzJ-P*1>wJ`H3H{J1DrwL3sdUZ!42dQIMWUS@U@Z4-e_U?6|%jXg217Wkl zI=_qMW@r2!RhZ+Xj95WD&C5@HWxlWR7%5g@vR_GBSihUDj(8N;O!&A`~nA5w;-$9k8Hj2!HPr^h)^tOE1$hVj0MpC|+=f_<-B`+rHaovvJ z6>Ehjhbwr`7vGIkKZaU~ek@fZJZ2SAhjJh`qRSkj%K+Mg#e(eYCVJke^@v?bzK~`% zXcfwZ*KgR*Iby}c)QWYT^0t)w^-*5sT;^92W0F&g#uxGxa^u{xa${C{e&nXBxr})~ zLy$YX;&QXd?W%81g(Gs4@B`1pCI$Imt670|an&)r{k(R>tX{j;52bYt25rE9qG^ZDJ(Fl704WBA$V=w~1MzsrhvDZGd# zOvg&UD+$)T&wke%KN+9bpE4U6Yd`#n=SK!saSC?Jhm07zy;NktGFZb}cXlBNX~#!E z1?<%wbLoelS+}yd(goc0G5kqf+ey%-&Z}(RquT&F&p&ZdZvM$j`OSF=au*w`{GmhSh!vr zlJ3kgG2b>GbKr;y(=euU;^>}e8tJk*87=&N`Y9xChC>-D#!g>1r#{|Q6GNsYf+gdf z55h;w#S5_+UoRdDqY?Eau42fss0{k6RvhS+C86kkRKL;9py>KNvHKGJONSyxON}Bo z!=WgO*)>z4$k!R)RA_lAmYmj5?+X(x7f%H}pu=iK@zY%A^OBJARaE8wW{?thLQ+n? zxnK3E+DVvKW+SFY4828crbAJ)N$z=EA>&m3Czn%^q1mALJjA&^$=`_V;Rk7~i^v^3 zqp|(I@$|eN&%L5No)~>MKXUXe`jlK_eR;<2@9n%8MW#RFp(q+Vw>}n}pG6Jlz$*?f z+DQt_jk@Wj{7vh0F6H}s$#o&qT6>5)-w9TvmWSso#o{Bo`nL*ysO@|5yJN0$vaL}a zu&iQwyKRQOcB4GE&0x^_LZwjN9Zq6$H`m!%>o90Do*D*!7F!Q(9VL&`)%?CWpzlch zC%%`~#~@a3%Zr`ZS!@n9rlXAQ_^~+usQU^ z=z*)y6Las^*_3^Jr_~H(=UP~Fzhn%>+DxCD<(4Xwe{;BriI|s-n`aVZ-JdNtxdY9A zp&mPBa!;yU^vz)?CPG~{hRE6@n_16C(k`MeMXe*3&(*i_$U&vuakkR$qAKXg5Ggc< z*;De-+l^e)1&n=%_ULuUu2nQqgWz{gH;FQsuDvJQ7yh z*7^MF;z-tmcnTcVM3csI>0(L--i2@xaie$g8z}P8Mz3GuxM~v;p>_FrV9~{MZwe|O z3ogHqXLNB|--vGAR>XGMlYh@@Ike$Vx2;V$EXP zCEo2G<>@LQHoZ2P8?j@w$xR}b{3J4+v_FWVvzzIb^2}3t-nlR*exP;L;0#U0+88v! zgx|}U$JI$n4!{1GCGg_sV6~DJmLmr-F57IVOPMAX2*j%4A(r|*R|E!*G4DPAxBS?#+%Cc-t$`TBUIQE$vj zjjJ`B3a;$5*feO0iG26Pkj-!k$N{}-g`voBc7UE3V7+0jH-M_C>ih9G;_X~H&U*Cm zmcp;Q9aUA^)=kY4O36WYqw3_lP}iKzaC`5oq;b5M2u)wC*bIkaCB_W<{nqM{c zNSK7qGjuS-i?jYw{)!GW$P=;o?CdA)Vp!*tr9=Y5uQLug`MQ4Q##z3Z=SO9_cwjD6 z#?+~mVEffksrg^pVYD9>>&UBDNzVwIQa4fhmZXgDs|qT)LQDE)-5BM(3jtuM8an)k4qU@clE3&8d!P zou>MFYWa|ex^Y|n#oYOFY{)K~Fl-leU6t0qOIK}>3t=%DOKFxQ>bv=Lu72Q=?9At) zlc;@Z{dFwkO!?2nZA!5}!5cjhV-(rkc++gy9Rn_&$ICg9VjM2h-!8#qHt;M?; zPC*-KcXRteVwrnl3!-4Wt1LnEMLHt#JFzaZvVN(a^NS#gM~~#Y*+2czQ&&>_Yr~&Q zd(GRrxUtA*d$nJ+$qS*+y^C8mG4rn1ZO(nDX8D!uROzx#7%lwy_r;~nF!cGX;6eN;~@~N_Mn`f&&l}G(<#;VwmgQ8Y%|5*CW zvF0mmht->^A}JqMrxLMfW7U`v)V&eTBs*xt|bDH|j*H?;bO7z4kr0e*i9TBO|v{V%N{6oC(RP0Ua zxvalS-CoqQ0Tc~m^!MB8^_ z!)d<=V{=Y?Gi;iD_fT-GQ3&)AG)#SlkM(Y^&VNSJzw`e#p4aBHdh0znzm`0`lvZK- z4o7Z=LlG9kgSM_us&$UP;xfZRI)=YOeMN(s)noYw$G|lBKrRmkY_yT~R34?G;nxbA zzsZ$&NOX<%U*$ScluvcY&1(5(o|gkbsPX%Ft1}luV^CItwdo_Y$#bdD=ku)A*^-6h z_arjTb^0eL2j}!)VV`K%In{T77t$kiS=$xXF=x9Ql0RDaeEnyPW8QqooA(U!V|{P+ zuSt8UFIw;mC*f^K(+AsHsRN#`otrZe54RwQhmIG=gS>9(AA2m-+>9TYkLur1RR?)wc z5s1K-guI!v>Z%R3mFZNQxJu1+tGvs;vl&jozS|SdITn=Nsw_7bv34CM$jk&UYTGF) z>wR*aU8r5>-MQkZq4;^A^FX5WdNn`miIs{&;_szkZuZyAtFrHT&ll7F1nCg1n#@#D|XecGSB4s=(pIg$33xGS5$ml zhd-6J{aE+lIK3#wE@_WrUQS96ZYRnn&S{6*y0mvU)`!cBo|sRr1f4VvJ^Ny9694mU zN6ql{*ZlQ+ZZl$heUKHdIaX;oCpK@ZKkxXnodWmxis3^+2-zlwmHoH+M52-q!}^F( zSXXn5b%RcK(%zlXOq1rMJs&+OIVV4QroufwdN_~rwS2iVfK)9+cgLI3bM|KJ)X(s6 z7Nh2Jm57~G%Avz!*tQ-zir00;2k?U3z#v?4H1~=Ziv)K&oqv!APsqMP4Yj-^-O~tPBQ8oKSAuFOwZ+0A6 zrcZ=Dm#Qa^!(-T*Shw%5$4*Qh*(yf5UZ2RZirj4=FsX&szLracg2xA z)SZdrY`c89OPfHSp*ckkLq7DyuuK`~)6CgVl~woKpLhdzGuDU@g!a&`HNOp5qhnNR z{anWkTNM2n&!27R6T2?l`L-Q%@H=`~ZY+M3>;I3vcqEv7Bbl+rgeZiU@=t#+$-m+Z znV5ZVGxlN`ir?3jy_hzKNXN{9B7e41K#^K9mQ8-E!j#Ju_iL%hQ`b%dSeNvGTZ(d_ zYP(|2dfpt0m5GY+@ha|Q@nAn&oooFr;hOWVuMB6n&Io<+nJ?;<&+5yK=X^8o;%>7q z&37H+ErO@i9I9jHLch&+3h3|Z<=Axsz|S?T`Yardk>%1O^R4L_jTYH%W`r0T4dE#~ z$oy!Gv8YP0XosN@m5}<9Cg)<^IzHuOo&&Lg`(gLCjD1VKo?OM#^@N}1IN_bNji^od zckNfTb!*HN+M~PJZ4)!^dfn#SQ?P2vD0+Sz$3#O)z_GK%cfJy5hY6oPHwN}}ap(D*l%&6_83;?H&p7~B)Ik)3=fY=_!} z6{~gBs_q&ZA9`p+PttDx-^#NcPc9dAKb7Y(igrLCKY-3Z%}nUN9xVGX$|$z6Dqd*J z`Z{W3*A=VqPTRIqH-Ve>tJ(_x+^u87P-^QqFXE?S9j`+C|0xJ3-_3dqZ3@fac*gA} zcAOkut#+3FQZnVnM~K{5;XOOfI(8#Yr!L9&AITzer}gmL!Ics;`=lZ3s%y1x1Io-w z7-|PQOyocrvkQGPCHS7`KXhT%tRd@6`9Z8;vxV)v))|5C7XJ|2;Psy#*ym`UI@G{* znj2gu0;gk#b~78NK)$PL1*s40+b_>&PwmQ1&rxhlG9|Q|Gm4V=jwrp_FU;@UekvX% z{_yQuye7P}wSBrxFi!hbjUzr+r0Q9bX)ID5EBx8VTcrN%rofecmoR#<=sB&{D^syT zhF|^6WW^X-k};|4wCQu|Y{`b!z_wYk_r+J_%eu#oiLAiOZoHHzb)$~+9b+uwb$dsj zYOOX>zZZUcFWE!n5YShe+I%!!dM%;MJ{6`tlgIR216QH1Hu|yrg;T+1jDBty{Yr3^ zBJv47b*z-w^k*0PWJ>Th9}B*yB~+^tym1DQ^~qQ+{w05*ibb<<-^g$0f;yLjtB;eH zpywtKSs{a-+=jQ6txUagJ?;^XtK^H5&gV0`j!q5%<71d^tQ=^HVX6|)MCK_zA~hu% zi{v-X6gd}<5xWzFku9(6#Un1V`JrOLQ+YNWpVJ_z?sfWX8UCEw-kb9otzvV?-4s}e%ed+4)M1FoCKka+g>;1)}#Sij0+3P`;k1g zv6^T;l*VMyt>V;8qO`4rlHJA`t}!-ly#i!LT=HBt{xak^MKO(*WGvURp#Th(zhoPswA-ou@Fn*Hf4wxDXM_Nr5lQseh{ zpr)+abHDVom9JJ{)Au&(DE0p`4za3}ejU}Xvm6X|d3)je&~;UF7a6MP>?X_O2G@)h zen0(?=w>(tB+}1&J|~?RCGnOVS)>}3h&%Z&FLIR0((%}C6*nL2F}1nO#+^=9OOwxt zThOEXP#6a-=98>0^ppd6)aR6LThV_;PCoj)&NKHJ=id#@{f5M0EL-6>@d@lq?L)ET z*ZEeQF8H9z-c=^S3%ena9n0gTb{ubjsu;~@TE#a0NXC^q(uJ%Wd=$-w!rP!imDP0i zXI@2k)Z2eXByULciMGqDdD1rowXek+WJdUL+TTXc&m^`OGuHh- zXZT2F*zDQg|E?2Z*Y&0GNqkaP!ns6RV&+36S+9R4pF4M(+yg%UAFoET+`5?2=vl6# zvDY_~jhcI|_zi-oOm5cGSs zI!xoJe+H}-eP?_|p!P&Y@^@D23)Z|p_PCzMdPnSTLvY`BYS;FEr*4;9%D(+UG#l{E zd(wAvCi|G*S8~WZyC?6=beg{J%&r~w&R_|Rvikcur-$g72z;)qQRF@!_Dyz&W4S|` ziEC^3hK&C~vKH6}|B$<;9CBPe-**50Yk?j%wzu`YV|MM>I~KpA#@#2fH;AD9QlSL} z@O%(XZc8qc?c4qDjb1zU-mFGPXykP(Db*diFFT*@`hD+^T^o8I?LG6b@)XgVunl~? ztzy2ob;CM2uJ%|kroFv1D>pUj?#a3`JFM@0vunrRH|$XQaBH0onUVB((RV%WKIYh` zIH$$z!~S1WtpMl?$IXKnx4Ks%&v($xxJ0iqbute-wPZ0mfXiv z`Cql-TNQsDi9e3bGlc1H3u_H!db_s&dLSo|Oh?^Y%}T?f|3lsf`nSf?;G9GG8q4^p z_G$djq5HI5o9b@)(RK70>{#wq$eW7W!}IJt_XpoSP7L7A_rH5+4sZY5eeeXFpQm|2 zk7eDFEfgMo6Slw|iPH_`G`qI{UHT|{2sm6y<}NwASyvBel{wEb=B97++fJ|4fg3_>*kKUThn&?@1lBb|M!aq`blQ2HXi$f>g8zX zte;`;Wk(oc=x1lwj(soc1>%h;N7yGd1-pzcpF@2@yLRmT+mkgxgvsvP_wv)^s|n#O;~;c=l24)yNs+97uc6(1YcPNZD+f7%pFr6=~ffFz5M>M3L-Q^^?18>%zI?7KNp<> z{f9jb{E#KdxxA=cM}u|)a+8KyG?a+5h z)V8VT?hB@|_&{3;=Ck562IIUBjhHVcVAqD;e^WtHYoK{w)!rh*0VQEi?)e+}iCkZe zT0WFdfRWba55=hp-S<3I|NPQhQu80+7$28a@p9yo0*(#E2sba9Yxsq##y-PCD!Jp>) zQa$BPKW}##-;-x@KX|9%S6s)%sThE)$f0-6uI+p0OqsyP;!co7s`)9Zvkh4R;BBat zY1a;aA5UZr9Lgul3RhLI|8B$G9J<@swPW7__6q8~#uBY(#p+C5vtia}q!J|`y2k9< z;qUB6*-h~RQe>dgOMIwuW!DaWC-|Xn1Sy(-Z;I6rw2&h+)b6uuhrbVYLG`WCR6^sd z+XX}FWIEr2XxdN(&aMr;)28p?_Q`$OAz8&2^7*TcweFje+*fuE zPST{3C5;MtUv|sk`=wsn|DC=5|GPWao;|9nkN2ZAzHf*WDEba6ASzTNpo#H?Z7C!o zH5>vp;k&zkv+h50*n4Kp{?A;O_iadgpikE|d!3Ja?Q(i5yWCYI?|g5-NFDskN`+%- z*{JJAl!A4r^rG;YjC;J7*zYBNSz<^xCK9Z3cIMKiaq#E&UK=vW$iRq+-Y-^wN|O>OHstdkiNflJ$B} ze1LqL-a%6D+~E+i?@urVY(F-yirlex011oCm|hsRM)|UX3sa1)CJD9|m-h-5aku+6 z-(%sHad=Gr;O6v#buf88)TpqRVM*wqX_TFz84$dVwTv&l&r$9nFZ`6F#Sv6?9-wV%UI3H z0(qs~vzy!$0M@}Us+&{*v4!8?L@3Y79+UTroqSe!7;gl=Q{vTnGf4i;Yv?}r;@xaS zu*YaO?aOLnXg(i(b}Vw1-K10P+7Q8Bf_Bl(oX!<0VphelU&lDF>mvkvKCam&(0)9r z^ZGHESA#*mM_ba;2PRzi?NRN=81A^%Q?Tc8Hu86MlZiT)9>R;QnMZN$oM0U+$G90^ zem-7w7kqgQ*j~KwZfqNRI(Rv1?(?YD;}BgU!v#2yo2wHylDw_$+xK&d!(Z-t~m<&>gV=0{QZAaBB^O*99?EGV9#9Hcx#Kh zUf+~|zAx7NSnb^Ja?{ly+V97Pvop~VH{7ZIlY7P8gpg)`x}Nz(w|^>F52M&Qu3V$F z?c1|f+`e`7O|ZQfeK1sClo5Yc{>f|{kc1+>r@%Hr1!~y`Q6ce zI$CZgNwEFW8Ta;?;+oG{+>Hp2Sl_F1QK@mNT)!>i;?al62Ft(O<$97<=LOYrw`%eAAtpLVni1ge>$%=@Hcb=s-H95 z({t^OVEZ}4D>IsP!<&yalQZ7PIIr^S-{ryec9IFY->0qbK& zOcVDanS>*z{dcKu#WY!TX^&~Xmv^2U7rGXMxX{TBmM_(PQtZQ;Rdu2de|HWYZD%I# zqaqpK-n=u5Umy~>Jv(}_53c|Pd9?99K-F`VuY zpqkHAzjhQyy$ZRQZk*AJNc|E{Ki$oI1bd91c=ay^EBIZph@MxcI`7T}2=*8j)4T4| zUCfS`g03z$g6+qKmkp^$Xl^JvkD0!W`5roVtm8x;?cy!iYvGO5##`WVljwu;-?6!F z+U;=kaeTS9cZ)cgiBpsMs8|>Ao}DGy7<)!Poin-qLa@C&{kUL&B*%R4J0+(4(8?8v zX8l+=VEfNL-wg3?vH!%r&kIg52f)U9YKYj(<8eVNW^`;88J{}=BG{v}qK0-C?%<%M zu1*N{D6Qu6uI=d($9g?HP*(}q~XA+>=)%9X?;I;*z4+6y#(8j z2Ya3#l&HNmeazmkt#=9gaU=qFV+g^zIEL?(t!9FS{vKVPV|o2q6+OCd{%l*o_R{7_ znXIRZL)~+nY=}C@Z;EFlw~<6=zr9r@K95GP7YXwEn^e@Dsi);e#F&24TwA{V#nFZxS`(aW($Jtr`?%-iL-n&`M8^73ic=^*o+<%0aU)uo^U;j zQp_f~K1;Cul#0y=bU78foI797mI1d`E!cjnh+H3(d+5ZmRAYFZ)rlkM9=kjdtaEzq z#cSr^F4#M8^|RD~JxV8ZTW@9g_YL5;FRuaXVKQz*V7i3*A+>4r)7|S&{_jRVg7t9u z(d-Ekhq}}kZ10KxRA^1aMxV0oYh}N7?Wl~NiOW;LW;iXQGN|&RNMhV=Q;nW3XH3Pi zKl-em_a!1(I#g~XD_DnS{~G*GWP{Hp7Jd0@m*bg;65YCxV2|OntVZ+S*^9;f865Q) zH#ZgRnRt3rzSt%=3Kr~9ET&U=cO$0o@5$i3kQ#?(^}Y@K@ugpGq@U(yjDmHroxff- zo!D30k^SnmJs|$ijmZU@;Z%FTm!)@0oIw3yx^)#V$n-oF3U0O&N#t^OZJJ?2+!;#2 zIy58i;=TH#-IPm21>`KQ2Ni5DO?dB?s^Ie?OUMfSrcX-j#Qx#e?)|RF&{H!{ecg_5 z@RCGF=isuOitqRMOhdVR5v+p?H3Mc5)aRf=&!6R#Iik&HPV)ZBwu@BSu&MoYi)RW-Cd!3^QOU@E`v?`i2-^3!&0o zXiDUneeZukLswU!A+Q-vOJ7W$!CY0y+(^UN)DZ7aK`mb97(F%A>$gRm(e;~xJ%-S~F$WePJ7)>h?9%;Gf~I%l_a8y@s=>obCNDTKWxs;4i{D=m(dpl0cwU$Fh>*Tft#WZXrF zn9{R!+uckcZiu2Wl^Z?dQ(YmfVGk3%4qKOXY2Z zo6oLu&+;zJ7jg66rIcX%Ws3Wj5gV>e7sYmabq>*+e-2ud`^K%<;H(Ze`L=5(1$%^Q z+U2#ZRO9EN6fb!?_8%|p;w9K4c*ShP`vnJf7)8HfeG40T8WB(IG110^$S<4-nb|@& zZVT9RasT~*-P7TJ$wu)XV2LL9FBSW>BD&jNp2J?~h)$W$VB>(^K$=$_J-29+w72r^fRS$guz&Yu+0qNXt@yiN z75(O66|QjV^%OpAzgbx_vy@@A3WR zuz}pIsb3?%cC>w76_>k5ZY&|#OVF7LNbC%y8gf_WaJm12@BMYLzP&ed1$&H|s@Q!~ z>XDxox<#$&?#d@V(zOGEJw{P_Xfa<;RCEdd>i3tqt>yJmrV#}B$@m7{-S7|06uEXw zut()$N;NMgCO7x7aQmop-hWx5{O?LHamDN*n-XQSZYUXCX8F>&jyYYA@jG6%#u^X zaHp;W>tRB)`C{;hV^3T!l1{fS&0qF(bQ62z;wV@L$EfOrM$!SH=EEcf(*blQKP^(u zYa_8cnM&Oy;vQ-`uJ04xcIdJ6O z_WZ@tyqf;ejTa&(!NximW9!{0O0XWr*q5{FlKu`pvL>pwy*PY!cq}6TW`?+#^K!60^i;1i%jifx)h^fP3f7@dY+#6(=s$x7hsAoWM9Az# ze?H_~KMvZ#{&2lNbxf)*k%7^*cdeyhdnrgK^&dCAW$ee-Lrvz@AZbCz+earh)4B10 zU>!O=EiyE(=s0?Ue{l6gu>GeeYm7<+F(;l5TSJd|oX+{M{Mom~!qA=6pB~$%NM7hl zv|xL2{cGXT9|lg<)kWRKh8kb2`uAxk@27?D`9Z0ygPa#p|i_XUUb=Rr5^5Sr6_Ya3U<5eKQ7GGdt1 zTOGFL_plgk%Eb4yM|TOgPNRThGlQ(rem)W5wofyqUdXgdd2C&ag6la!V1&hy%^4{V zUDwVWaMX7c-(89l{JtZDkABvrDMk+yj5L=&mxL0a{-|we{GNd_1 z5e>BEQ8F>kl1wR>X$LdOqQn#~(?;qQlBFqJ#xe2)Rc@wmoM8(;Bv-RCQ@Hh;E&MHB zUt?-5tn?HvqYHeH)#!oalr7!N=*cbMnh&`(#d zZ#mJt8lyap)Bd-myk#1Tg{U=l>vm62e!8`1r2HPec&ljv*CjZ<_g1lit#fAhVR2g) zew~-X?_u+t`S->xAtPOKz1O71l7E>7P-Sj;q6|OX;+cOhv|>wh)IprXq_6r`Z56gzjLydAB$*oi$_>WN%@qw zncc;YanhwMWpL`0&*7*(Zp#wds0dz6VG}NoUjzL)c_;zjZBB{5Ig%nc#oBCMb0@K)>bkXt*j`= z?@^O~>#_sYBcgAeGp}NK8i3`I&DyWi>s)GCQ+U&FO_6_5e*ek(JhOK)WL`9z>dJb& z61=4%Q|okIk-P4=W#5DEEqbn7iQpf(Y0dXN z6{mI16qO^oU=s@yq3tcv^Ppl9sk@16m#f zZE-wCJ08wrCZq!0=+!gmR`WNXEWqBi>|~~Az}0fGhri=)(NUiAm=LR6%hSHfZi_A% zepuz2E_ptKe)8K({$=(~n=Sj{#+MC8dWH{c%XruW;+bpcnWH(cHz=QTn%KBy`LUK; zl)z5aaJglK#-iYq@|k22K{=X(-`4joX&L)D2Ca0mkrMlCK}*LnUrnc>rDHj#TfQ^r zG#qQ$5Ts^Xvf90dOhPzOO_w|tA*-y!Q+ twJ*-;iIlbEGnbcfdf-wTzOGy6#y++D?xEZ3O}T(>Q>*mT@LxaO`!9?_SHS=P literal 0 HcmV?d00001 diff --git a/ATAPHtmlReport/runATAP.ps1 b/ATAPHtmlReport/runATAP.ps1 new file mode 100644 index 0000000..2c7712f --- /dev/null +++ b/ATAPHtmlReport/runATAP.ps1 @@ -0,0 +1,42 @@ +#set the directory where you want to save the reports +$report_directory = "~\Documents\ATAPReports" +#enter which report you want to execute +$report_name = "Microsoft Windows 10" +#saves old working directory +$old_pwd = $pwd + +#to access the report file later, "Microsoft" has to be cut out of the String +if($report_name.Contains("Microsoft")) { + $report = $report_name.Substring(10, ($report_name.Length-10)) +} +else { + $report = $report_name +} + +#starts generating the HTML report +Save-ATAPHtmlReport $report_name -Path $report_directory -MITRE + +#enters the report_directory and searchs for the newest report of the kind set above +Set-Location $report_directory +if ($null -eq (Get-ChildItem -Name)) { + Write-Output 'Error no report could be generated.' +} +elseif((Get-ChildItem -Name).GetType().Name -eq 'String') { + $file = Get-ChildItem -Name + #opens the report with the standard appplication set in windows + Start-Process -FilePath $file + #goes back to the old working directory + Set-Location $old_pwd +} +elseif((Get-ChildItem -Name).GetType().Name -eq 'Object[]') { + $i = ((Get-ChildItem -Name).Length)-1 + $file = $report_directory + "\" + (Get-ChildItem -Name)[$i] + while(!$file.Contains($report)) { + $i = $i - 1 + $file = $report_directory + "\" + (Get-ChildItem -Name)[$i] + } + #opens the report with the standard appplication set in windows + Start-Process -FilePath $file + #goes back to the old working directory + Set-Location $old_pwd +} \ No newline at end of file diff --git a/FAQ/images/FAQ_print backgrounds.PNG b/FAQ/images/FAQ_print backgrounds.PNG new file mode 100644 index 0000000000000000000000000000000000000000..14e6aeddb4f59edb6f79a8dad5699aef1d6b9369 GIT binary patch literal 4521 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 literal 0 HcmV?d00001 diff --git a/Installer/icons/AT128.png b/Installer/icons/AT128.png new file mode 100644 index 0000000000000000000000000000000000000000..be44362dfd2f64704c53c2b157b350f810d391fa GIT binary patch literal 2620 zcmbtW_dDAQ7yl-<*sj_&uh~?@E{fQ>r1mI^TCI}W6}t(wsn)%? zE*d*_QEJE4_j&(<_kGTD#`Afe^ULRRo^#G0CPuof%>2v%0I(t+YX5eTF~6LV{vvj% zIt>B5>zHDcG+sN7d7I@;SJ{PLF>=dCos2yBX}79Ye4`=uh)`G(Gk z9NT%#f^nL@m?a+$dZ}D9cJYvOJ{v@Ea|#(SWbVOi@k~*9X~3=O^{6RwZ{v(I=yZgb zIsVh~DsftTb-(e7Dww`8GI708>^mr1iTEX5mM=~C$dfr1yd4fFXVB1lM|LO@2;-_o zf*6*756@|!Q1F7zfc?RW7+)+h|gcg%3sUd%gYtz4`}(iI{CZ0 z2nBiidkEqx3SH8Q)EE`#|DTv zx(B@U(GDudCdprdxQtz!j&KR4G@a0U#!mjW##oo>!(#*2;n8N!xN_{s;Ds1{Lp!>6 zBsmh~(6q23o$@Vot37z-;73-$+f&t7ep~k`1;`W;1lYQc_lU~`&;&8k32|fox1yBo zjSII__X2Nw*wxgd;O<~v7J6kHD{Ncw4f8dHyQ)cu>boUTdB|EJGRjy5R0VxNJL15W z;O=tg_ZjkeT*W^&MNgN-#lId82(k~tKmc)a*EmBd|D8OoK}h==tsv0pwAXRYW57s{ z8eJdmo29{gY*qTO3}{(al^0SD$d{53Iib4n;uAH0h>$=c>8xM8g0hZ6!Ik-!aI#~C zU~qJ_m51d=2FAe0y(>hZBxeoGV%L(96>J7TuyLB(3eWNRfNs(aerCDicT&U|YPhzF zz$WdFXXt}?LEf*AAVfcE+fUc$Co;mh3E&tvce&lKy1Ci%zANmS_4T+X6-+SSA7Z7= z!NY^8%ga9Eq|V+jIbI1&R+Fu505YZWyQ`%&^sc=i?#knX8KXN1g`Xn!6;!>*#pL9Vy;lyNDlaz^uPwTmsawOjHL^)y1(acI*mCS8>HC5SAk zNBO(s8a$n8DfB0HLSyeWBb^CcfjjDLheluve%_h8+JOzI@%kqHn9bOX%UM~X_#@EK zp{nD)@iZcwZF%}JK-9})4gR1Mv&ONt8GSx31Gn}DWo(^J7DiABU8MEu#EGR&I=Hnl zC`w+w$;{!FlHKR;cZzE2b_pt-@*`Nagz>vVoGiCTLoRe#h%3%l>+J|TC+s!jUjySo zWR6hi{>j|>s#EDcCo#-oa=>9SOXh%QVJW+NeQ$pP*B}5M!X@268&Kzs?Kdyu8z#3- zyhX>xU{<@I#LD8=YhfzG9!MF?g$kxEW8Q5$v(2PBR|yrgI^KB>21iXhHhkb#PZMb} z%1_h@|#V*TN7x z)8D{@pYt{MS?$~7h_gb%)meZ*>>$2!9B-O|a^0ujxxUWHmT{~&!jN?lTAZX)vMrz{JMA&@Rrqf!0)tq64w%ufoO|mOq$W61aIAcva!^9BYnmV@ z_f}Tkr^SjGQI^a*^kgN7IC66B!m#HQ`ukiL8@x~3BNUv&ouj~gThw0-&^cI}ogKIO(Kei%`R*S zeVoLJsYEOKz-&LtN75l@Smxt#d(6qrrR4Bs)^*dy(7U+F$qI8-fj@|Tc&1cp_*`4u zKU1c&XcG)WEle@CRX15mc4ab}!L-GvWR11P!hCMGQYrR_kDyZA+FkNrOKw#SP%ylu zh5P%dtEFmWZ$Y?CI(-J-mccBFO<3j$;&m$nwJ>}hIvdGV7I9|lbKUji0NHqe8t9Mo zIuAGB-F2DeN|FK_kXz$-jMdC#G0eIxf^qMc@0;&hCse21(gRX&PWTe;IlV9c(!eo3 zpyy(#di|C05GA_0IvIS*k4QtGd}8XRySKLH2zwGL{^4Q}y~wHoaiD7*$P^1Ou65?6 z()o+sE$i69f-B~q$KO{hE+9SB(M;`n1tyrH!EA_o!NC(5i;S$bQFf%OXx&5=_C{Eip_>I|-ujwR!oFP;bhp<|?7rRf;;F97b%761SM literal 0 HcmV?d00001 diff --git a/Installer/icons/AT16.png b/Installer/icons/AT16.png new file mode 100644 index 0000000000000000000000000000000000000000..3c0a6b20a36fddbf8aec0ff6f5b501cce278c8f2 GIT binary patch literal 904 zcmV;319$w1P)EX>4Tx04R}tkv&MmKpe$iQ>7{u2Rn#31gTCIL`57+6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UmP&La) z#baVNw<-o+As~QW_%SLmQ%|H9Gw>W=_we!cF2b|C&;2?2mAuISpGX{Kx?vG-5YKK} zI_G`j5GzRv@j3B?K^G)`9%C|}6B ztZ?4qtX68Qbx;1nU|w5EbDic0;#figNr;e9Lm3rVh|sE$Vj@NRF%SQ+<4=-HCRZ7Z z91EyIh2;3b|KNAGW?_2DO$x?eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00Cf0L_t(I%hi*=O9EjS$3LE4aCdP@w;V-nL9_@8fe!ru z5ggn41DtKB|DjrIEgLMFwb7{*TeLPY&cHOtM27-7%Db*X(1b|AsRy3n;miBs{k#va z%W)is2})qXni$~uIds}>+SMum^FAMLkB8TCnU7BA*Tai}z%anbWO&%!10ZyjX2I{L zba_ehs3()i z>uWR(gDJ0fNMqy{T9pc2qu00BH~p}FaL8vY#*`%eeS@c54glX-f?zsDFr7l#+yJ04 zLPM}Ei|6xmq)?FMNQA{epx0YlV`;b?$8p{p4Ma&onwjYbUDL#Td&4b?D4N!vMOj8t e)nUN@{!HKA1ccf6gr1=Q000008w8- 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 literal 0 HcmV?d00001 diff --git a/Installer/icons/AT32.png b/Installer/icons/AT32.png new file mode 100644 index 0000000000000000000000000000000000000000..9357f807904202d76a9e3e458669b7f89cdd064e GIT binary patch literal 1136 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